home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / c / gcc-2.005 / gcc-2.7.2-p1.patch
Encoding:
Text File  |  1996-01-30  |  935.3 KB  |  31,236 lines

  1. diff -rNci gcc-2.7.2/combine.c gcc-2.7.2p/combine.c
  2. *** gcc-2.7.2/combine.c    Sun Nov 26 19:32:07 1995
  3. --- gcc-2.7.2p/combine.c    Tue Jan 23 09:53:17 1996
  4. ***************
  5. *** 97,102 ****
  6. --- 97,106 ----
  7.   #include "recog.h"
  8.   #include "real.h"
  9.   
  10. + /* intel1 */
  11. + static int in_recombine=0;
  12. + extern FILE *combine_dump_file;
  13.   /* It is not safe to use ordinary gen_lowpart in combine.
  14.      Use gen_lowpart_for_combine instead.  See comments there.  */
  15.   #define gen_lowpart dont_use_gen_lowpart_you_dummy
  16. ***************
  17. *** 386,391 ****
  18. --- 390,418 ----
  19.   
  20.   static int n_occurrences;
  21.   
  22. + /* intel2 - begin */
  23. + #define INSN_SETS_REGNO(INSN, REGNO) dead_or_set_regno_p (INSN, REGNO)
  24. + #define INSN_USES_REGNO(INSN, REGNO) refers_to_regno_p (REGNO, \
  25. +                             REGNO + 1, \
  26. +                                                         PATTERN (INSN), \
  27. +                                                         0)
  28. + /* if this flag is set do not recombine unscheded riscified insns, which their
  29. +  * original insn's destination was a memory.
  30. +  */
  31. + extern int flag_risc_mem_dest;
  32. + /* if this flag is set try to riscify stores of CONST_INTs */
  33. + extern int flag_risc_const;
  34. + void update_free_regs (rtx);
  35. + static void update_regno_holds_mem (rtx insn, rtx pat);
  36. + static int remove_redundant_store (rtx mem, int block);
  37. + static void update_entries (rtx reg);
  38. + /* intel2 - end */
  39.   static void init_reg_last_arrays    PROTO(());
  40.   static void setup_incoming_promotions   PROTO(());
  41.   static void set_nonzero_bits_and_sign_copies  PROTO((rtx, rtx));
  42. ***************
  43. *** 445,450 ****
  44. --- 472,486 ----
  45.   static void distribute_notes    PROTO((rtx, rtx, rtx, rtx, rtx, rtx));
  46.   static void distribute_links    PROTO((rtx));
  47.   static void mark_used_regs_combine PROTO((rtx));
  48. + static int try_forwards_replace PROTO((rtx, rtx, rtx, FILE *));
  49. + /* intel2 */
  50. + #if 0
  51. + static void dump_free_registers ();
  52. + #endif
  53. + int find_free_reg();
  54. + static int find_regno_holds_mem (rtx, enum machine_mode);
  55. + /* intel1 */
  56. + static int try_backwards_replace ();
  57.   
  58.   /* Main entry point for combiner.  F is the first insn of the function.
  59.      NREGS is the first unused pseudo-reg number.  */
  60. ***************
  61. *** 881,886 ****
  62. --- 917,925 ----
  63.   
  64.     /* Don't eliminate a store in the stack pointer.  */
  65.     if (dest == stack_pointer_rtx
  66. +       /* intel1 
  67. +       || (in_recombine && GET_CODE (dest) == REG
  68. +           && reg_used_between_p (dest, insn, i3)) */
  69.         /* If we couldn't eliminate a field assignment, we can't combine.  */
  70.         || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == STRICT_LOW_PART
  71.         /* Don't combine with an insn that sets a register to itself if it has
  72. ***************
  73. *** 1059,1064 ****
  74. --- 1098,1105 ----
  75.      On machines where SMALL_REGISTER_CLASSES is defined, we don't combine
  76.      if the destination of a SET is a hard register that isn't a user
  77.      variable.
  78. +    intel2 - This is true unless we are in recombine (indicated by
  79. +    in_recombine)
  80.   
  81.      Before doing the above check, we first try to expand a field assignment
  82.      into a set of logical operations.
  83. ***************
  84. *** 1128,1139 ****
  85. --- 1169,1194 ----
  86.            CALL operation.  */
  87.         || (GET_CODE (inner_dest) == REG
  88.             && REGNO (inner_dest) < FIRST_PSEUDO_REGISTER
  89. +           /* intel2 - begin */
  90. +           /* if we are in the recombine phase, we should not eliminate the
  91. +            * possibility for combine if the destination is a hard register.
  92. +            */
  93. +           && (!in_recombine)
  94. +           /* intel2 - end */
  95.             && (! HARD_REGNO_MODE_OK (REGNO (inner_dest),
  96.                       GET_MODE (inner_dest))
  97.   #ifdef SMALL_REGISTER_CLASSES
  98.            || (GET_CODE (src) != CALL && ! REG_USERVAR_P (inner_dest))
  99.   #endif
  100.             ))
  101. +       /* intel2 - begin */
  102. +       /* if we want to leave mem-dest riscified instructions untouched... */
  103. +       || (in_recombine
  104. +         && flag_risc_mem_dest
  105. +         && GET_CODE (inner_dest) == MEM)
  106. +       /* intel2 - end */
  107.         || (i1_not_in_src && reg_overlap_mentioned_p (i1dest, src)))
  108.       return 0;
  109.   
  110. ***************
  111. *** 1389,1394 ****
  112. --- 1444,1468 ----
  113.         return 0;
  114.       }
  115.   
  116. +   /* intel1 */
  117. +   if (in_recombine)
  118. +     {
  119. +       if (i1 && GET_CODE (PATTERN (i1)) == SET 
  120. +           && GET_CODE (SET_DEST (PATTERN (i1))) == REG
  121. +           && reg_used_between_p (SET_DEST (PATTERN (i1)), i1, i2))
  122. +         {
  123. +           undo_all ();
  124. +           return 0;
  125. +         }
  126. +       if (i2 && GET_CODE (PATTERN (i2)) == SET 
  127. +           && GET_CODE (SET_DEST (PATTERN (i2))) == REG
  128. +           && reg_used_between_p (SET_DEST (PATTERN (i2)), i2, i3))
  129. +         {
  130. +           undo_all ();
  131. +           return 0;
  132. +         }
  133. +     }
  134.     /* Record whether I2DEST is used in I2SRC and similarly for the other
  135.        cases.  Knowing this will help in register status updating below.  */
  136.     i2dest_in_i2src = reg_overlap_mentioned_p (i2dest, i2src);
  137. ***************
  138. *** 2021,2026 ****
  139. --- 2095,2142 ----
  140.         = recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches);
  141.       }
  142.   
  143. +    /* intel1 , maybe we can rearrange memory so it is recognized */
  144. + #ifdef REWRITE_ADDRESS
  145. +    if (insn_code_number==-1 && GET_CODE(newpat)==SET && i1==NULL)
  146. +      {
  147. +        rtx copy_of_newpat,try_to_make_good(); /* see loop.c */
  148. +        rtx new_src_copy,new_dest_copy;
  149. +        int dummy;
  150. +        char * storage;
  151. +        storage = (char *) oballoc(0);
  152. +        copy_of_newpat = copy_rtx (newpat);
  153. +        new_src_copy = SET_SRC (copy_of_newpat);
  154. +        try_to_make_good (SET_SRC (copy_of_newpat));
  155. +        try_to_make_good (SET_DEST (copy_of_newpat));
  156. +        if (recog (copy_of_newpat, i3, &dummy) != -1)
  157. +          {
  158. +            int scrat;
  159. +            newpat = copy_of_newpat;
  160. +            insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes, &scrat);
  161. +          }
  162. +        else if (GET_CODE (new_src_copy) != MEM)
  163. +          {
  164. +            new_src_copy = gen_rtx (MEM, GET_MODE( new_src_copy), new_src_copy);
  165. +            try_to_make_good (new_src_copy);
  166. +            SET_SRC (copy_of_newpat) = XEXP (new_src_copy,0);
  167. +            if (recog (copy_of_newpat,i3,&dummy) != -1)
  168. +              {
  169. +                int scrat;
  170. +                newpat = copy_of_newpat;
  171. +                insn_code_number = recog_for_combine (&newpat,i3,&new_i3_notes,&scrat);
  172. +              }
  173. +            else
  174. +              {
  175. +                obfree (storage);
  176. +              }
  177. +          }
  178. +        else
  179. +          {
  180. +            obfree (storage);
  181. +          }
  182. +      }
  183. + #endif /* REWRITE_ADDRESS */
  184.     /* If it still isn't recognized, fail and change things back the way they
  185.        were.  */
  186.     if ((insn_code_number < 0
  187. ***************
  188. *** 2031,2036 ****
  189. --- 2147,2176 ----
  190.         return 0;
  191.       }
  192.   
  193. +  /* intel2 - begin */
  194. + #ifdef REGISTER_CONSTRAINTS
  195. +    /* check if the combined insn is a legal one */
  196. +    if (in_recombine)
  197. +      {
  198. +        register rtx temp_pat = PATTERN (i3);
  199. +        register int temp_code_number = INSN_CODE (i3);
  200. +        /* change it only for the following check */
  201. +        PATTERN (i3) = newpat;
  202. +        INSN_CODE (i3) = insn_code_number;
  203. +        insn_extract (i3);
  204. +        /* restore the data */
  205. +        PATTERN (i3) = temp_pat;
  206. +        INSN_CODE (i3) = temp_code_number;
  207. +        if (! constrain_operands (insn_code_number, 1))
  208. +          {
  209. +            undo_all();
  210. +            return 0;
  211. +          }
  212. +      }
  213. + #endif
  214. +  /* intel2 - end */
  215.     /* If we had to change another insn, make sure it is valid also.  */
  216.     if (undobuf.other_insn)
  217.       {
  218. ***************
  219. *** 4248,4253 ****
  220. --- 4388,4401 ----
  221.         int other_changed = 0;
  222.         enum machine_mode compare_mode = GET_MODE (dest);
  223.   
  224. +     /* intel1 */
  225. + #ifdef HAVE_cc0
  226. +     if(SET_DEST (x) == cc0_rtx && compare_mode==VOIDmode)
  227. +       {
  228. +         compare_mode = GET_MODE (SET_SRC (x));
  229. +       }
  230. + #endif
  231.         if (GET_CODE (src) == COMPARE)
  232.       op0 = XEXP (src, 0), op1 = XEXP (src, 1);
  233.         else
  234. ***************
  235. *** 9912,9918 ****
  236.     for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
  237.       {
  238.         if (REG_NOTE_KIND (link) == REG_DEAD
  239. !       && GET_CODE (XEXP (link, 0)) == REG)
  240.       {
  241.         int regno = REGNO (XEXP (link, 0));
  242.         int endregno
  243. --- 10060,10072 ----
  244.     for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
  245.       {
  246.         if (REG_NOTE_KIND (link) == REG_DEAD
  247. !           /* intel2 - begin */
  248. !           /* if in_recombine we might encounter a REG_DEAD note of memory!
  249. !            */
  250. !           && (! in_recombine
  251. !               || GET_CODE (XEXP (link, 0)) == REG)
  252. !           /* intel2 - end */
  253. !            )
  254.       {
  255.         int regno = REGNO (XEXP (link, 0));
  256.         int endregno
  257. ***************
  258. *** 10755,10806 ****
  259.   
  260.         if (place == 0)
  261.           {
  262. !           for (tem = prev_nonnote_insn (i3);
  263.              place == 0 && tem
  264.              && (GET_CODE (tem) == INSN || GET_CODE (tem) == CALL_INSN);
  265.              tem = prev_nonnote_insn (tem))
  266. !         {
  267. !           /* If the register is being set at TEM, see if that is all
  268. !              TEM is doing.  If so, delete TEM.  Otherwise, make this
  269. !              into a REG_UNUSED note instead.  */
  270. !           if (reg_set_p (XEXP (note, 0), PATTERN (tem)))
  271. !             {
  272. !               rtx set = single_set (tem);
  273.   
  274. !               /* Verify that it was the set, and not a clobber that
  275. !              modified the register.  */
  276.   
  277. !               if (set != 0 && ! side_effects_p (SET_SRC (set))
  278. !               && (rtx_equal_p (XEXP (note, 0), SET_DEST (set))
  279. !                   || (GET_CODE (SET_DEST (set)) == SUBREG
  280. !                   && rtx_equal_p (XEXP (note, 0),
  281. !                           XEXP (SET_DEST (set), 0)))))
  282. !             {
  283. !               /* Move the notes and links of TEM elsewhere.
  284. !                  This might delete other dead insns recursively. 
  285. !                  First set the pattern to something that won't use
  286. !                  any register.  */
  287. !               PATTERN (tem) = pc_rtx;
  288. !               distribute_notes (REG_NOTES (tem), tem, tem,
  289. !                         NULL_RTX, NULL_RTX, NULL_RTX);
  290. !               distribute_links (LOG_LINKS (tem));
  291. !               PUT_CODE (tem, NOTE);
  292. !               NOTE_LINE_NUMBER (tem) = NOTE_INSN_DELETED;
  293. !               NOTE_SOURCE_FILE (tem) = 0;
  294. !             }
  295. !               else
  296. !             {
  297. !               PUT_REG_NOTE_KIND (note, REG_UNUSED);
  298. !               
  299. !               /*  If there isn't already a REG_UNUSED note, put one
  300. !                   here.  */
  301. !               if (! find_regno_note (tem, REG_UNUSED,
  302. !                          REGNO (XEXP (note, 0))))
  303. !                 place = tem;
  304. !               break;
  305.                 }
  306.             }
  307.           else if (reg_referenced_p (XEXP (note, 0), PATTERN (tem))
  308. --- 10909,10973 ----
  309.   
  310.         if (place == 0)
  311.           {
  312. !         for (tem = prev_nonnote_insn (i3);
  313.              place == 0 && tem
  314.              && (GET_CODE (tem) == INSN || GET_CODE (tem) == CALL_INSN);
  315.              tem = prev_nonnote_insn (tem))
  316. !           {
  317. !         /* If the register is being set at TEM, see if that is all
  318. !            TEM is doing.  If so, delete TEM.  Otherwise, make this
  319. !            into a REG_UNUSED note instead.  */
  320. !         if (reg_set_p (XEXP (note, 0), PATTERN (tem)))
  321. !           {
  322. !             rtx set = single_set (tem);
  323.   
  324. !             /* Verify that it was the set, and not a clobber that
  325. !                modified the register.  */
  326.   
  327. !             if (set != 0 && ! side_effects_p (SET_SRC (set))
  328. !              && (rtx_equal_p (XEXP (note, 0), SET_DEST (set))
  329. !                  || (GET_CODE (SET_DEST (set)) == SUBREG
  330. !                  && rtx_equal_p (XEXP (note, 0),
  331. !                          XEXP (SET_DEST (set), 0)))))
  332. !               {
  333. !             /* Move the notes and links of TEM elsewhere.
  334. !                This might delete other dead insns recursively. 
  335. !                First set the pattern to something that won't use
  336. !                any register.  */
  337. !             PATTERN (tem) = pc_rtx;
  338. !             distribute_notes (REG_NOTES (tem), tem, tem,
  339. !                       NULL_RTX, NULL_RTX, NULL_RTX);
  340. !             distribute_links (LOG_LINKS (tem));
  341. !             PUT_CODE (tem, NOTE);
  342. !             NOTE_LINE_NUMBER (tem) = NOTE_INSN_DELETED;
  343. !             NOTE_SOURCE_FILE (tem) = 0;
  344. !               }
  345. !             else
  346. !               {
  347. !               /* intel1 making this into reg_unused causes
  348. !                  bug in scheduler since sched will see this
  349. !                  as a reg_dead */
  350. ! #if 0
  351. !             PUT_REG_NOTE_KIND (note, REG_UNUSED);
  352. ! #endif
  353. ! #if 0
  354. !             /*  If there isn't already a REG_UNUSED note, put one
  355. !                 here.  */
  356. !             if (! find_regno_note (tem, REG_UNUSED,
  357. !                            REGNO (XEXP (note, 0))))
  358. !               place = tem;
  359. ! #else
  360. !           /*  If there isn't already a REG_DEAD note, put one
  361. !               here.  */
  362. !           if (! find_regno_note (tem, REG_DEAD,
  363. !                          REGNO (XEXP (note, 0))))
  364. !             place = tem;
  365. ! #endif
  366. !             break;
  367.                 }
  368.             }
  369.           else if (reg_referenced_p (XEXP (note, 0), PATTERN (tem))
  370. ***************
  371. *** 10826,10832 ****
  372.                 }
  373.               break;
  374.             }
  375. !         }
  376.             
  377.             /* If we haven't found an insn for the death note and it
  378.            is still a REG_DEAD note, but we have hit a CODE_LABEL,
  379. --- 10993,10999 ----
  380.                 }
  381.               break;
  382.             }
  383. !           }
  384.             
  385.             /* If we haven't found an insn for the death note and it
  386.            is still a REG_DEAD note, but we have hit a CODE_LABEL,
  387. ***************
  388. *** 11100,11103 ****
  389. --- 11267,13846 ----
  390.       (file,
  391.        "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n",
  392.        total_attempts, total_merges, total_extras, total_successes);
  393. + }
  394. + /* intel1 */
  395. + /* intel1 - those split insns that remained consecutive should now
  396. +            be combined 
  397. + */
  398. + void
  399. + combine_unscheded (f, nregs)
  400. +      rtx f;
  401. +      int nregs;
  402. + {
  403. +   register rtx insn, next, prev;
  404. +   register int i;
  405. +   register rtx links, nextlinks, note;
  406. +   in_recombine = 1;
  407. +   combine_attempts = 0;
  408. +   combine_merges = 0;
  409. +   combine_extras = 0;
  410. +   combine_successes = 0;
  411. +   combine_max_regno = nregs;
  412. +   reg_last_death = (rtx *) alloca (nregs * sizeof (rtx));
  413. +   reg_last_set = (rtx *) alloca (nregs * sizeof (rtx));
  414. +   reg_last_set_value = (rtx *) alloca (nregs * sizeof (rtx));
  415. +   reg_last_set_table_tick = (int *) alloca (nregs * sizeof (int));
  416. +   reg_last_set_label = (int *) alloca (nregs * sizeof (int));
  417. +   reg_last_set_invalid = (char *) alloca (nregs * sizeof (char));
  418. +   bzero (reg_last_death, nregs * sizeof (rtx));
  419. +   bzero (reg_last_set, nregs * sizeof (rtx));
  420. +   bzero (reg_last_set_value, nregs * sizeof (rtx));
  421. +   bzero (reg_last_set_table_tick, nregs * sizeof (short));
  422. +   bzero (reg_last_set_invalid, nregs * sizeof (char));
  423. +   init_recog_no_volatile ();
  424. +   /* Compute maximum uid value so uid_cuid can be allocated.  */
  425. +   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
  426. +     if (INSN_UID (insn) > i)
  427. +       i = INSN_UID (insn);
  428. +   uid_cuid = (int *) alloca ((i + 1) * sizeof (int));
  429. +   /* Compute the mapping from uids to cuids.
  430. +      Cuids are numbers assigned to insns, like uids,
  431. +      except that cuids increase monotonically through the code. 
  432. +      Scan all SETs and see if we can deduce anything about what
  433. +      bits are significant for some registers.  */
  434. +   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
  435. +     {
  436. +       uid_cuid [INSN_UID (insn)] = ++i;
  437. +       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
  438. +     note_stores (PATTERN (insn), set_nonzero_bits_and_sign_copies);
  439. +     }
  440. +   label_tick = 1;
  441. +   last_call_cuid = 0;
  442. +   mem_last_set = 0;
  443. +   /* Now scan all the insns in forward order.  */
  444. +   for (insn = f; insn; insn = NEXT_INSN (insn))
  445. +     {
  446. +       if (GET_CODE (insn) == CODE_LABEL)
  447. +     label_tick++;
  448. +       if(GET_CODE (insn) == INSN)
  449. +     {
  450. +       /* Try this insn with each insn it links back to.  */
  451. +       for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
  452. +         {
  453. +           if(REG_NOTE_KIND (links) != REG_DEP_ANTI 
  454. +              /*&& REG_NOTE_KIND (links) != REG_DEP_OUTPUT 
  455. +              && */ && (GET_CODE (XEXP (links, 0)) == INSN 
  456. +                   && next_nonnote_insn (XEXP (links, 0))
  457. +                        == ORG_NEXT_INSN (XEXP (links, 0)))
  458. +              && GET_CODE (PATTERN (XEXP (links, 0))) == SET
  459. +              && GET_CODE (SET_DEST (PATTERN (XEXP (links, 0))))
  460. +                   == REG
  461. +              && (note
  462. +                   = find_regno_note (insn,
  463. +                                      REG_DEAD,
  464. +                       REGNO(SET_DEST (PATTERN (XEXP (links, 0))))))
  465. +              && rtx_equal_p (XEXP (note, 0),
  466. +                               SET_DEST (PATTERN (XEXP (links, 0))))
  467. +          /* intel2 - begin */
  468. +          /* combine only insns that were created by memory_simplify.
  469. +           */
  470. +          && (RTX_IS_RISC_P (XEXP (links, 0)))
  471. +          /* intel2 - end */
  472. +             )
  473. +             {
  474. +           /* intel2 - begin */
  475. +           rtx inner_link = LOG_LINKS (XEXP (links, 0));
  476. +           int three_insns = 0;
  477. +           /* Check that we consider the case of three-insns riscified
  478. +            * insn
  479. +            */
  480. +           if (inner_link)
  481. +             {
  482. +               for (; inner_link; inner_link = XEXP (inner_link, 1))
  483. +                 {
  484. +                   rtx temp_insn = XEXP (inner_link, 0);
  485. +                   if (REG_NOTE_KIND (inner_link) != REG_DEP_ANTI
  486. +                       /*&& REG_NOTE_KIND (inner_link) != REG_DEP_OUTPUT
  487. +                       &&*/ && (GET_CODE (temp_insn) == INSN
  488. +                           && next_nonnote_insn (temp_insn) ==
  489. +                                   ORG_NEXT_INSN (temp_insn))
  490. +                       && RTX_IS_RISC_P (temp_insn)
  491. +                       && GET_CODE (PATTERN (temp_insn)) == SET
  492. +                       && GET_CODE (SET_DEST (PATTERN (temp_insn)))
  493. +                            == REG
  494. +                       && (note
  495. +                            = find_regno_note (insn,
  496. +                                               REG_DEAD,
  497. +                                REGNO(SET_DEST (PATTERN (temp_insn)))))
  498. +                       && rtx_equal_p (XEXP (note, 0),
  499. +                                        SET_DEST (PATTERN (temp_insn)))
  500. +                     )
  501. +                     {
  502. +                       try_combine (insn, XEXP (links, 0), temp_insn);
  503. +                       three_insns = 1;
  504. +                     }
  505. +                 }
  506. +             }
  507. +           if (! three_insns)
  508. +             {
  509. +              /* intel2 - end */
  510. +                  try_combine (insn, XEXP (links, 0), 0);
  511. +                }
  512. +             }
  513. +         }
  514. +     }
  515. +       if(GET_CODE (insn) == INSN ||
  516. +          GET_CODE (insn) == CALL_INSN ||
  517. +          GET_CODE (insn) == JUMP_INSN)
  518. +       record_dead_and_set_regs (insn);
  519. +     }
  520. +   in_recombine = 0;
  521. + }
  522. + /* intel2 - begin */
  523. + /* we will probably need this - check it and remvoe it if not... */
  524. + /*#include "hard-reg-set.h"*/
  525. + /* Set of registers that are free and ready to use at this moment.  */
  526. + HARD_REG_SET free_regs;
  527. + /* Set of registers that are not recommended for allocating at this moment.  */
  528. + static HARD_REG_SET not_recommended_regs;
  529. + typedef struct {
  530. +   rtx mem;  /* mem rtx, this regno holds */
  531. +   rtx insn_dead;  /* insn in which this regno dies */
  532. +   rtx insn_load;  /* insn in which this regno is loaded */
  533. +   rtx insn_store;  /* insn in which this regno is stored */
  534. + }  MEM_HOLDER;
  535. + /* Indexed by regno, indicates which register currently, holds a copy of
  536. +    memory and the rtx represents this memory, as well as the insn loaded it,
  537. +    and the insn in which this register was dead. */
  538. + MEM_HOLDER regno_holds_mem[FIRST_PSEUDO_REGISTER];
  539. + /* Perform simplification of memory accessed instructions by replacing them
  540. +    with risc-like instructions.
  541. +    FILE is a file to output debugging information on,
  542. +    or zero if such output is not desired.  */
  543. + void
  544. + memory_simplify (file, f)
  545. +      FILE *file;
  546. +      rtx f;
  547. + {
  548. +   register int block, j;
  549. +   int regno, limit;
  550. +   int i; /* intel1 */
  551. +   int nregs; /* intel1 */
  552. +   char * fmt; /* intel1 */
  553. +   MEM_HOLDER *mhp;
  554. +   rtx copy_reg = NULL;
  555. +   rtx t_insn;
  556. +   /* record which is the last register used for a spill reload */
  557. +   static int last_load_reg;
  558. +   /* Initialize reg_holds_mem */
  559. +   bzero (regno_holds_mem, sizeof regno_holds_mem);
  560. +     
  561. +   /* since all registers now are hard registers, FIRST_PSEUDO_REGISTER is a
  562. +      valid initialization value */
  563. +   last_load_reg = FIRST_PSEUDO_REGISTER;
  564. +   hard_reg_flow_analysis (f, file, 0 /* no pseudo registers' info. save */ );
  565. +   if (n_basic_blocks <= 0)
  566. +     {
  567. +       return ;
  568. +     }
  569. +   /* To determine which registers are live after any insn, start from
  570. +      the beginning of the basic block and scan insns, noting
  571. +      which registers are set by each insn and which die there. */
  572. +   for (block = 0; block < n_basic_blocks; block++)
  573. +     {
  574. +       register rtx insn;
  575. +       int end_of_block_f;
  576. +       if (file)
  577. +     fprintf (file, "\nblock number: %d:\n", block);
  578. +       last_load_reg = FIRST_PSEUDO_REGISTER;
  579. +       /* since we cannot remove stores before a jump, we clean all the
  580. +          insn_store data */
  581. +       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  582. +     regno_holds_mem[regno].insn_store = 0;
  583. +       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  584. +         /* at the beginning of a block, each non-live hard register is
  585. +        considered free. */
  586. +     {
  587. +       register int offset = regno / REGSET_ELT_BITS;
  588. +       register int bit = 1 << (regno % REGSET_ELT_BITS);
  589. +       if (basic_block_live_at_start[block][offset] & bit)
  590. +         CLEAR_HARD_REG_BIT (free_regs, regno);
  591. +       else
  592. +         SET_HARD_REG_BIT (free_regs, regno);
  593. +         }
  594. +       /* Traverse the block, an insn by insn, check for memory references,
  595. +      and find whether a risc-like insns instead are valid. If yes,
  596. +      replace the insn by another insn(s). */
  597. +       end_of_block_f = 0;    /* signals the end of block reached */
  598. +       for (insn = basic_block_head[block];
  599. +        !end_of_block_f;
  600. +        insn = NEXT_INSN (insn))
  601. +     {
  602. +       rtx note, next, mem_opr = 0;
  603. +       rtx pat = PATTERN (insn);
  604. +       int regno, old_regno;
  605. +       int saved_code;
  606. +       /* try to eliminate as much stores as we can using the free_regs
  607. +          and regno_holds_mem information */
  608. +       if (GET_CODE (insn) == INSN
  609. +           && GET_CODE (pat) == SET
  610. +           && GET_CODE (SET_DEST (pat)) == MEM
  611. +           && GET_CODE (SET_SRC (pat)) == REG
  612. +           && GET_CODE (XEXP (SET_DEST (pat), 0)) != PRE_DEC
  613. +           && GET_CODE (XEXP (SET_DEST (pat), 0)) != PRE_INC
  614. +           && GET_CODE (XEXP (SET_DEST (pat), 0)) != POST_DEC
  615. +           && GET_CODE (XEXP (SET_DEST (pat), 0)) != POST_INC
  616. +           && (i = remove_redundant_store (SET_DEST (pat), block))
  617. +           && file)
  618. +         fprintf (file,
  619. +                  "insn %d caused a deletion of a redundant store: %d\n",
  620. +                      INSN_UID (insn),
  621. +                      i);
  622. +       /* Try to eliminate as much loads as we can using the free_regs
  623. +          and regno_holds_mem information */
  624. +       else if (GET_CODE (insn) == INSN
  625. +            && GET_CODE (pat) == SET
  626. +            && (GET_CODE (SET_DEST (pat)) == REG
  627. +                || GET_CODE (SET_DEST (pat)) == MEM)
  628. +            && (GET_CODE (SET_SRC (pat)) == MEM
  629. +                || (GET_CODE (SET_SRC (pat)) == CONST_INT
  630. +                    && flag_risc_const)))
  631. +         {
  632. +           int simple_copy_f = 0;
  633. +           rtx set_src = SET_SRC (pat);
  634. +           rtx set_dest = SET_DEST (pat);
  635. +           enum machine_mode mode = GET_MODE (set_dest);
  636. +               if (GET_CODE (SET_DEST (pat)) == REG)
  637. +             old_regno = REGNO (set_dest);
  638. +           else
  639. +             old_regno = FIRST_PSEUDO_REGISTER;
  640. +           if (old_regno != FIRST_PSEUDO_REGISTER
  641. +               && (next = next_nonnote_insn (insn))
  642. +                     && GET_RTX_CLASS (GET_CODE (next)) == 'i'
  643. +               && ((note = find_regno_note (next, REG_DEAD, old_regno))
  644. +                   ||
  645. +                   (GET_CODE (PATTERN (next)) == SET && 
  646. +                    rtx_equal_p (set_dest, SET_DEST (PATTERN (next)))))
  647. +               /* tevid */
  648. +               && (note == NULL 
  649. +                   || mode == GET_MODE (XEXP (note, 0))))
  650. +             {
  651. +           rtx new_reg = NULL;
  652. +               rtx old_reg = set_dest; 
  653. +               int stop_replacement = 0;
  654. +               /* if this load is redundant (i.e. the memory loaded
  655. +                  exists in any register, and the register we're loading
  656. +                  to will die in the next insn), we can replace loaded
  657. +                  register in the next insn with the already loaded register,
  658. +                  and delete this insn.
  659. +               */
  660. +               if ((regno = find_regno_holds_mem (set_src, mode))
  661. +                                    != FIRST_PSEUDO_REGISTER
  662. +                && HARD_REGNO_NREGS (regno, mode) == 1
  663. +                && regno_holds_mem[regno].insn_load
  664. + #ifdef STACK_REGS
  665. +                && (STACK_REG_P (old_reg)
  666. +                || NON_STACK_REG_P (new_reg = gen_rtx (REG,
  667. +                            mode,
  668. +                            regno)))
  669. + #endif
  670. +                && TEST_HARD_REG_BIT (free_regs, regno))
  671. +             {
  672. + #ifdef STACK_REGS
  673. +                       if (!new_reg)
  674. +                 new_reg = gen_rtx (REG, mode, regno);
  675. + #endif
  676. +               /* replace this register in the next insn */
  677. +                       init_undo_buf ();
  678. +                       saved_code = INSN_CODE (next);
  679. +               subst_in_insn (next,
  680. +                            PATTERN (next),
  681. +                            old_reg,
  682. +                            new_reg,
  683. +                            0,
  684. +                            0);
  685. +               if (note == NULL)
  686. +                 { /* Then the dest of next must remain old_reg */
  687. +                   SET_DEST (PATTERN (next)) = old_reg;
  688. +                 }
  689. + #ifdef REGISTER_CONSTRAINTS
  690. +                   INSN_CODE (next) = recog (PATTERN (next), next, 0);
  691. +                   if (INSN_CODE (next) != -1)
  692. +                 insn_extract (next);
  693. +               if (INSN_CODE (next) == -1
  694. +                   || !constrain_operands (INSN_CODE (next), 1))
  695. +                 {
  696. +               /* restore the previous situation */
  697. +               loop_undo_all();
  698. +               INSN_CODE (next) = saved_code;
  699. +                   stop_replacement = 1;
  700. +                  }
  701. + #endif
  702. +               if (!stop_replacement)
  703. +                 {
  704. +                   
  705. +               if (regno != old_regno)
  706. +                 {
  707. +                   if (note != NULL)
  708. +                     {
  709. +                       /* The regno in the REG_DEAD note should be
  710. +                          also changed */
  711. +                           XEXP (note, 0) = new_reg;
  712. +                   
  713. +                           /* Now, if we replaced a REG_DEAD note, and
  714. +                              the new_reg is the destination of the next
  715. +                              insn, we should remove this note */
  716. +                           if (GET_CODE (SET_DEST (PATTERN (next)))
  717. +                                == REG
  718. +                           && REGNO (SET_DEST (PATTERN (next)))
  719. +                                == regno)
  720. +                             remove_death (regno, next);
  721. +                         }      
  722. +                       /* replace the registers in the free_register
  723. +                          list */
  724. +                       nregs = HARD_REGNO_NREGS (old_regno, mode);
  725. +                       for (i = 0; i < nregs; i++)
  726. +                         SET_HARD_REG_BIT (free_regs, old_regno + i);
  727. +                       nregs = HARD_REGNO_NREGS (regno, mode);
  728. +                       for (i = 0; i < nregs; i++)
  729. +                         CLEAR_HARD_REG_BIT (free_regs, regno + i);
  730. +                     }  /* if (regno != old_regno) */
  731. +                   else
  732. +                   /* regno == old_regno */
  733. +                     {
  734. +                       /* mark that regno is not free anymore */
  735. +                       nregs = HARD_REGNO_NREGS (regno, mode);
  736. +                       for (i = 0; i < nregs; i++)
  737. +                         CLEAR_HARD_REG_BIT (free_regs, regno + i);
  738. +                     }
  739. +                   /* now we can delete this insn ... */
  740. +                   if (basic_block_head[block] == insn)
  741. +                     basic_block_head[block] = NEXT_INSN (insn);
  742. +               mhp = ®no_holds_mem[regno];
  743. +                           /* we should reset the RISC flag on the insns
  744. +                          added for risc, so that they will not be
  745. +                  recombined later */
  746. +               
  747. +               if (mhp -> insn_dead)
  748. +                 {
  749. +                   t_insn = PREV_INSN (mhp->insn_dead);
  750. +                   while (t_insn && RTX_IS_RISC_P (t_insn))
  751. +                     {
  752. +                       RTX_IS_RISC_P (t_insn) = 0;
  753. +                       t_insn = PREV_INSN (t_insn);
  754. +                     }
  755. +                   remove_death (regno, mhp -> insn_dead);
  756. +                   if (! t_insn)
  757. +                     /* something went wrong */
  758. +                     abort ();
  759. +                 }
  760. +                   if (file)
  761. +                     fprintf (file,
  762. +                              "insn %d: deleted - redundant "
  763. +                              "load encountered (insn %d)\n",
  764. +                              INSN_UID (insn),
  765. +                              INSN_UID (mhp -> insn_load));
  766. +                         
  767. +               PUT_CODE (insn, NOTE);
  768. +                   NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
  769. +                   NOTE_SOURCE_FILE (insn) = 0;
  770. +               /* ... and start working on the next insn */
  771. +                   continue;
  772. +              }  /* if (!stop_replacement) */
  773. +                   
  774. +             }  /* if ((regno = find_regno_holds_mem (set_src)) !=
  775. +                                FIRST_PSEUDO_REGISTER
  776. +                        && TEST_HARD_REG_BIT (free_regs, regno)) */
  777. +                  
  778. +           else if (regno != FIRST_PSEUDO_REGISTER)
  779. +             /* regno holds the appropriate value but is not free, 
  780. +                so we can use its contents to
  781. +                convert this insn to a simple reg to reg copy */
  782. +             {
  783. +               copy_reg = gen_rtx (REG, mode, regno);
  784. + #ifdef STACK_REGS
  785. +               if (GET_CODE (SET_DEST (pat)) != REG
  786. +                   || (STACK_REG_P (SET_DEST (pat))
  787. +                               == STACK_REG_P (copy_reg)))
  788. + #endif
  789. +                         {                  
  790. +                   simple_copy_f = 1;
  791. +                 }
  792. +             }
  793. +               else if (old_regno == last_load_reg
  794. +                && (regno =
  795. +                     find_free_reg (GET_MODE (SET_DEST (pat)))) !=
  796. +                        FIRST_PSEUDO_REGISTER
  797. +                    && regno != old_regno)
  798. +                 {
  799. +               new_reg = gen_rtx (REG, mode, regno);
  800. +                   /* replace this insn's register with regno */
  801. +                   SET_DEST (pat) = new_reg;
  802. +               /* replace this register in the next insn and its
  803. +                  REG_NOTES */
  804. +               init_undo_buf ();
  805. +               saved_code = INSN_CODE (next);
  806. +               subst_in_insn (next,
  807. +                          PATTERN (next),
  808. +                          old_reg,
  809. +                          new_reg,
  810. +                          0,
  811. +                          0);
  812. +               if (note == NULL)
  813. +                { /* Then the dest of next must remain old_reg */
  814. +                  SET_DEST (PATTERN (next)) = old_reg;
  815. +                }
  816. + #ifdef REGISTER_CONSTRAINTS
  817. +                   if ((INSN_CODE (next) = recog (PATTERN (next),
  818. +                              next,
  819. +                              0)) != -1)
  820. +                 insn_extract (next);
  821. +               if (INSN_CODE (next) == -1
  822. +                   || !constrain_operands (INSN_CODE (next), 1))
  823. +                 {
  824. +               /* restore the previous situation */
  825. +                       SET_DEST (pat) = old_reg;
  826. +                       loop_undo_all ();
  827. +                     INSN_CODE (next) = saved_code;
  828. +                   stop_replacement = 1;
  829. +                  }
  830. + #endif
  831. +               if (!stop_replacement)
  832. +                 {
  833. +                   if (note != NULL)
  834. +                     {
  835. +                   /* The regno in the REG_DEAD note should be
  836. +                      changed */
  837. +                       XEXP (note, 0) = new_reg;
  838. +                   
  839. +                       /* Now, if we replaced a REG_DEAD note, and the
  840. +                          new_reg is the destination of the next insn, we
  841. +                          should remove this note */
  842. +                       if (GET_CODE (SET_DEST (PATTERN (next))) == REG
  843. +                       && REGNO (SET_DEST (PATTERN (next))) == regno)
  844. +                         remove_death (regno, next);
  845. +                 }
  846. +                   /* replace the registers in the free_register
  847. +                      list */
  848. +                   nregs = HARD_REGNO_NREGS (regno, mode);
  849. +                   for (i = 0; i < nregs; i++)
  850. +                     CLEAR_HARD_REG_BIT (free_regs, regno + i);
  851. +                   nregs = HARD_REGNO_NREGS (old_regno, mode);
  852. +                   for (i = 0; i < nregs; i++)
  853. +                     SET_HARD_REG_BIT (free_regs, old_regno + i);
  854. +                   /* replace relevant data in regno_holds_mem */
  855. +                   regno_holds_mem[regno].mem = set_src;
  856. +                   regno_holds_mem[regno].insn_load = insn;
  857. +                   regno_holds_mem[regno].insn_dead = next;
  858. +                   if (file)
  859. +                     fprintf (file, 
  860. +                     "insn %d: replacing reload register %d with register %d\n",
  861. +                 INSN_UID (insn), old_regno, regno);
  862. +              }  /* if (!stop_replacement) */
  863. +                   
  864. +                 }  /* else if (old_regno == last_load_reg
  865. +                    && (regno =
  866. +                   find_free_reg (GET_MODE (set_dest))) !=
  867. +                               FIRST_PSEUDO_REGISTER)
  868. +                */
  869. +           else if (old_regno == last_load_reg
  870. +                && file)
  871. +             fprintf (file,
  872. +                  "insn %d: no free register found for reload."
  873. +                      "\n", 
  874. +                  INSN_UID (insn));
  875. +             }  /* if ((next = next_nonnote_insn (insn))
  876. +                           && GET_RTX_CLASS (GET_CODE (next)) == 'i'
  877. +                     && (note = find_regno_note (next, REG_DEAD, old_regno)))
  878. +                    */
  879. +           else if ((regno = find_regno_holds_mem (set_src, mode)) 
  880. +                     != FIRST_PSEUDO_REGISTER
  881. +                 && HARD_REGNO_NREGS (regno, mode) == 1)
  882. +         {
  883. +           copy_reg = gen_rtx (REG, mode, regno);
  884. + #ifdef STACK_REGS
  885. +           if (GET_CODE (set_dest) != REG
  886. +               || (STACK_REG_P (set_dest) == STACK_REG_P (copy_reg)))
  887. + #endif
  888. +                     simple_copy_f = 1;
  889. +             }
  890. +           if (simple_copy_f)
  891. +         {
  892. +           MEM_HOLDER *mhp_org;
  893. +           rtx mem;
  894. +                 
  895. +           /* we can change this insn to a simple reg copy, instead
  896. +              of a load or store */
  897. +           mem = SET_SRC (pat);
  898. +           if (copy_reg == NULL)
  899. +             {
  900. +               copy_reg = gen_rtx (REG, mode, regno);
  901. +             }
  902. +           saved_code = INSN_CODE (insn);
  903. +           SET_SRC (pat) = copy_reg;
  904. + #ifdef REGISTER_CONSTRAINTS
  905. +               if ((INSN_CODE (insn) = recog (PATTERN (insn),
  906. +                          insn,
  907. +                          0)) != -1)
  908. +             insn_extract (insn);
  909. +           if (INSN_CODE (insn) == -1
  910. +               || !constrain_operands (INSN_CODE (insn), 1))
  911. +             {
  912. +               SET_SRC (pat) = mem;
  913. +               INSN_CODE (insn) = saved_code;
  914. +             }
  915. +           else
  916. +             {
  917. + #endif
  918. +               /* now we should eliminate the possibility of the risc
  919. +                  sequence loaded the memory int regno, to be later
  920. +                  recombined */
  921. +               mhp_org = ®no_holds_mem[regno];
  922. +               mhp = ®no_holds_mem[old_regno];
  923. +               if (mhp_org -> insn_load)
  924. +             {
  925. +                   /* we should reset the RISC flag on the insns
  926. +                      added for risc, so that they will not be
  927. +                      recombined later */
  928. +               if (mhp_org -> insn_dead)
  929. +                 {
  930. +                   t_insn = PREV_INSN (mhp_org->insn_dead);
  931. +                   while (t_insn  && RTX_IS_RISC_P (t_insn))
  932. +                     {
  933. +                       RTX_IS_RISC_P (t_insn) = 0;
  934. +                       t_insn = PREV_INSN (t_insn);
  935. +                     }
  936. +                   if (! t_insn)
  937. +                     fprintf (stderr,
  938. +                              "Not encountered insn_dead\n");
  939. +                   remove_death (regno, mhp_org -> insn_dead);
  940. +                 }
  941. +             }  /* if (mhp_org -> insn_load) */
  942. +               /* we should update old_regno entries in
  943. +              regno_holds_mem array */
  944. +               mhp -> mem = mhp_org -> mem;
  945. +               mhp -> insn_load = insn;
  946. +               
  947. +               if (file)
  948. +                 fprintf (file,
  949. +                          "insn %d: mem source replaced with reg\n",
  950. +                          INSN_UID (insn));
  951. + #ifdef REGISTER_CONSTRAINTS
  952. +             }  /* else of if (INSN_CODE (insn) == -1
  953. +                            || !constrain_operands (INSN_CODE (insn), 1))
  954. +                */
  955. + #endif
  956. +         }  /* if (simple_copy_f) */
  957. +               if (GET_CODE (pat) == SET 
  958. +                   && GET_CODE (SET_DEST (pat)) == REG)
  959. +             last_load_reg = REGNO (SET_DEST (pat));
  960. +         }  /* if (GET_CODE (insn) == INSN
  961. +                       && GET_CODE (pat) == SET
  962. +                       && GET_CODE (SET_DEST (pat)) == REG
  963. +                       && GET_CODE (SET_SRC (pat)) == MEM) */
  964. +       /* mark all the original insns (those not created here). Since
  965. +          we use here the same bit as RTX_IS_SPILL_P, we should do this
  966. +          after checking for the spill reload register substitution. */
  967. +       RTX_IS_RISC_P (insn) = 0;
  968. +       end_of_block_f = (insn == basic_block_end[block]);
  969. +       if (!INSN_UID (insn))
  970. +         fatal ("\nMemory simplify: Scanning illegal insn.");
  971. +       if (GET_CODE (insn) == INSN)
  972. +         {
  973. +           register rtx note;
  974. +           if (GET_CODE (pat) == SET)
  975. +         {
  976. +           rtx prev_insn, next_insn;
  977. +           rtx insn_src = SET_SRC (pat);
  978. +           rtx insn_dest = SET_DEST (pat);
  979. +           int mem_opr_is_src = 0;
  980. +           /* indicates which of the two SET_SRC's arguments is a
  981. +              memory reference. 0 - indicates the first one and 1 -
  982. +              the second */
  983. +                  
  984. +           int mem_loc;
  985. +           switch (GET_CODE (insn_src))
  986. +             {
  987. +               case CONST_INT:
  988. +                 if (flag_risc_const
  989. +                     && GET_CODE (insn_dest) == MEM
  990. +                     && !push_operand (insn_dest, 
  991. +                                          GET_MODE (insn_dest)))
  992. +               {
  993. +                 mem_opr = insn_src;
  994. +                 mem_loc = 1;
  995. +                             mem_opr_is_src = 1;
  996. +                 /* this is a trick to make the code replacing
  997. +                    the memory operand in any other insn, valid
  998. +                    even here.
  999. +                    Note that insn_src now is actually the
  1000. +                    insn's pattern, and not the SET_SRC of it. */
  1001. +                 insn_src = pat;
  1002. +               }
  1003. +                         break;
  1004. +               case REG:
  1005. +               case SYMBOL_REF:
  1006. +             /* do nothing, this is a simple copy */
  1007. +             break;
  1008. +               case MEM:
  1009. +             if (GET_CODE (insn_dest) == CC0)
  1010. +               /* this insn is not a simple load */
  1011. +               {
  1012. +                 mem_opr = insn_src;
  1013. +                 mem_loc = 1;
  1014. +                             mem_opr_is_src = 1;
  1015. +                 /* this is a trick to make the code replacing
  1016. +                    the memory operand in any other insn, valid
  1017. +                    even here.
  1018. +                    Note that insn_src now is actually the
  1019. +                    insn's pattern, and not the SET_SRC of it. */
  1020. +                 insn_src = pat;
  1021. +               }
  1022. +             break;
  1023. +               default:
  1024. +                 if (GET_CODE (insn_src) == SIGN_EXTRACT
  1025. +                     || GET_CODE (insn_src) == ZERO_EXTRACT)
  1026. +                   { /* These cannot be handled properly */
  1027. +                     break;
  1028. +                   }
  1029. +             fmt = GET_RTX_FORMAT (GET_CODE (insn_src));
  1030. +             if (GET_CODE (XEXP (insn_src, 0)) == MEM)
  1031. +               {
  1032. +                 mem_loc = 0;
  1033. +                 mem_opr = XEXP (insn_src, 0);
  1034. +               }
  1035. +             else if (GET_RTX_LENGTH (GET_CODE (insn_src)) > 1
  1036. +                  && fmt[1] == 'e'
  1037. +                  && GET_CODE (XEXP (insn_src, 1)) == MEM)
  1038. +               {
  1039. +                 mem_loc = 1;
  1040. +                 mem_opr = XEXP (insn_src, 1);
  1041. +               }
  1042. +             break;
  1043. +             }    /* switch (GET_CODE(insn_src)) */
  1044. +           if (mem_opr)
  1045. +             /* we found a memory operand that we should replace */
  1046. +             {
  1047. +               int skip_load_f = 0;  /* should we skip mem load? */
  1048. +               int regno_is_free = 0; /* was it allocated by find_free_reg */
  1049. +               int memory_dest_changed  
  1050. +                            = GET_CODE (insn_dest) == MEM
  1051. +                               && rtx_equal_p (insn_dest, mem_opr);
  1052. +               enum machine_mode mode = GET_MODE (mem_opr);
  1053. +                       if (GET_CODE (mem_opr) == CONST_INT)
  1054. +                         mode = GET_MODE (insn_dest);
  1055. +               if ((regno = find_regno_holds_mem (mem_opr, mode)) 
  1056. +                    != FIRST_PSEUDO_REGISTER)
  1057. +             {
  1058. +               if (HARD_REGNO_NREGS (regno, mode) == 1
  1059. +                   && TEST_HARD_REG_BIT (free_regs, regno))
  1060. +                 skip_load_f = 1;
  1061. +               else
  1062. +                 regno = FIRST_PSEUDO_REGISTER;
  1063. +             }
  1064. +                       if (regno == FIRST_PSEUDO_REGISTER
  1065. + #ifdef IS_RISC_MODE
  1066. +                   && (IS_RISC_MODE (GET_MODE (mem_opr))
  1067. +                       || GET_CODE (mem_opr) == CONST_INT)
  1068. + #endif
  1069. +                          )
  1070. +                         { /* Look forward a few insns to see
  1071. +                              if this mem_opr will be loaded
  1072. +                              into a register and if it is then
  1073. +                              try to use that register for riscifying.  */
  1074. +                           t_insn = next_nonnote_insn (insn);
  1075. +                           while (t_insn && regno == FIRST_PSEUDO_REGISTER)
  1076. +                             {
  1077. +                               if (GET_CODE (t_insn) == CODE_LABEL
  1078. +                                   || GET_CODE (t_insn) == CALL_INSN)
  1079. +                                 {
  1080. +                                   break;
  1081. +                                 }
  1082. +                               if (GET_CODE (t_insn) == INSN)
  1083. +                                 {
  1084. +                                   register rtx dest;
  1085. +                                   
  1086. +                                   if (GET_CODE (PATTERN (t_insn)) != SET)
  1087. +                                     {
  1088. +                                       break;
  1089. +                                     }
  1090. +                                   dest = SET_DEST (PATTERN (t_insn));
  1091. +                                   if (GET_CODE (dest) == REG
  1092. +                                       && rtx_equal_p (mem_opr,
  1093. +                                           SET_SRC (PATTERN (t_insn))))
  1094. +                                     {
  1095. +                                       regno = REGNO (dest);
  1096. +                           nregs = HARD_REGNO_NREGS (regno, mode);
  1097. +                           if (HARD_REGNO_MODE_OK (regno, mode))
  1098. +                             {
  1099. +                               for (i = 0; i < nregs; i++)
  1100. +                                 if (! TEST_HARD_REG_BIT (free_regs,
  1101. +                                               regno + i))
  1102. +                                   {
  1103. +                                     regno = FIRST_PSEUDO_REGISTER;
  1104. +                                     break;
  1105. +                                   }
  1106. +                             }
  1107. +                           else
  1108. +                             regno = FIRST_PSEUDO_REGISTER;
  1109. +                                     }
  1110. +                                   else if (GET_CODE (dest) == MEM
  1111. +                                            && ! push_operand (dest,
  1112. +                                                          GET_MODE (dest)))
  1113. +                                     /* since there is a write to memory, no use
  1114. +                                        in trying to load something that might be
  1115. +                                        clobbered. */
  1116. +                         regno = FIRST_PSEUDO_REGISTER;
  1117. +                                 }
  1118. +                               t_insn = next_nonnote_insn (t_insn);
  1119. +                             }
  1120. +                                      
  1121. +                         }
  1122. +                       if (regno == FIRST_PSEUDO_REGISTER
  1123. +               && GET_CODE (insn_dest) == REG
  1124. + #ifdef IS_RISC_MODE
  1125. +                   && (IS_RISC_MODE (GET_MODE (mem_opr))
  1126. +                       || GET_CODE (mem_opr) == CONST_INT)
  1127. + #endif
  1128. +                          )
  1129. +             {
  1130. +               regno = REGNO (insn_dest);
  1131. +               nregs = HARD_REGNO_NREGS (regno, mode);
  1132. +               if (HARD_REGNO_MODE_OK (regno, mode))
  1133. +                 {
  1134. +                   for (i = 0; i < nregs; i++)
  1135. +                     if (! TEST_HARD_REG_BIT (free_regs,
  1136. +                                  regno + i))
  1137. +                       {
  1138. +                         regno = FIRST_PSEUDO_REGISTER;
  1139. +                         break;
  1140. +                       }
  1141. +                 }
  1142. +               else
  1143. +                 regno = FIRST_PSEUDO_REGISTER;
  1144. +             }
  1145. +                   if (regno == FIRST_PSEUDO_REGISTER
  1146. + #ifdef IS_RISC_MODE
  1147. +                   && (IS_RISC_MODE (GET_MODE (mem_opr))
  1148. +                       || GET_CODE (mem_opr) == CONST_INT)
  1149. + #endif
  1150. +                          )
  1151. +             {
  1152. +               prev_insn = prev_nonnote_insn (insn);
  1153. +               next_insn = next_nonnote_insn (insn);
  1154. +               /* update set of not recommended hard registers
  1155. +                  for find_free_reg () */
  1156. +               /* NOTE that we can refer only to integer
  1157. +                  registers, but now we do it more general. */
  1158. +               for (regno = 0;
  1159. +                    regno < FIRST_PSEUDO_REGISTER;
  1160. +                    regno++)
  1161. +                 if ((prev_insn
  1162. +                      && GET_RTX_CLASS (GET_CODE (prev_insn))
  1163. +                           == 'i'
  1164. +                      && (INSN_USES_REGNO (prev_insn, regno)
  1165. +                      || INSN_SETS_REGNO (prev_insn, regno)))
  1166. +                      || (next_insn
  1167. +                         && GET_RTX_CLASS (GET_CODE (next_insn))
  1168. +                                       == 'i'
  1169. +                  && (INSN_USES_REGNO (next_insn, regno)
  1170. +                      /* If the destination is MEM we
  1171. +                         might write the new register
  1172. +                         contents to the memory as the
  1173. +                         last insn. This will force us to
  1174. +                         also consider a write to the
  1175. +                         allocated register in the next
  1176. +                         insn. */
  1177. +                   || (memory_dest_changed
  1178. +                       && INSN_SETS_REGNO (next_insn,
  1179. +                                           regno)))))
  1180. +                   SET_HARD_REG_BIT (not_recommended_regs,regno);
  1181. +                 else
  1182. +                   CLEAR_HARD_REG_BIT (not_recommended_regs,
  1183. +                                 regno);
  1184. +               regno = find_free_reg (mode);
  1185. +               regno_is_free = 1;
  1186. +             }
  1187. +                   if (regno != FIRST_PSEUDO_REGISTER)
  1188. +             {
  1189. +               rtx new_insn, new_reg, link;
  1190. +               /* before changing the insn, and adding others, we
  1191. +                  check the changed insn will be legal. */
  1192. +               new_reg = gen_rtx (REG, mode, regno);
  1193. +               saved_code = INSN_CODE (insn);
  1194. +               if (mem_opr_is_src)
  1195. +                 {
  1196. +                   SET_SRC (pat) = new_reg;
  1197. +                 }
  1198. +               else
  1199. +                 {
  1200. +                               init_undo_buf ();
  1201. +                   subst_in_insn (insn, pat, mem_opr, new_reg, 0, 0);
  1202. +                 }
  1203. +                   
  1204. + #ifdef REGISTER_CONSTRAINTS
  1205. +               /* now check if the insn's O.K. */
  1206. +               INSN_CODE (insn) = recog (pat, insn, 0);
  1207. +               if (INSN_CODE (insn) != -1)
  1208. +                 insn_extract (insn);
  1209. +               if (INSN_CODE (insn) == -1
  1210. +                   || ! constrain_operands (INSN_CODE (insn), 1))
  1211. +                     {
  1212. +                   if (mem_opr_is_src)
  1213. +                     {
  1214. +                       SET_SRC (pat) = mem_opr;
  1215. +                     }
  1216. +                   else
  1217. +                     {
  1218. +                       loop_undo_all ();
  1219. +                     }
  1220. +                   INSN_CODE (insn) = saved_code;
  1221. +                 }
  1222. +               else  /* the replacement is valid */
  1223. +                 {
  1224. + #endif
  1225. +                   if (! skip_load_f)
  1226. +                     {
  1227. +                       if (mode != SImode && regno_is_free
  1228. +                           && GET_CODE (mem_opr) == CONST_INT)
  1229. +                         {
  1230. +                           new_reg = gen_rtx (REG, SImode, regno);
  1231. +                         }
  1232. +                       /* load the memory into regno */
  1233. +                       new_insn 
  1234. +                        = make_insn_raw (gen_rtx (SET,
  1235. +                                  VOIDmode,
  1236. +                                  new_reg,
  1237. +                                   mem_opr));
  1238. +                   RTX_IS_RISC_P (new_insn) = 1;
  1239. +                       add_insn_after (new_insn,
  1240. +                           PREV_INSN (insn));
  1241. +                   /* record regno as the last register that
  1242. +                     is used for loading */
  1243. +                   
  1244. +                   last_load_reg = regno;
  1245. +                   /* update new data in regno_holds_mem[] */
  1246. +                       
  1247. + #if 0
  1248. +                   mhp = ®no_holds_mem[regno];
  1249. +                   mhp -> insn_load = new_insn;
  1250. + #endif
  1251. +                   update_regno_holds_mem(new_insn,
  1252. +                              PATTERN(new_insn));
  1253. +                       
  1254. +                   /* if insn was the first insn in this
  1255. +                      block this should be updated */
  1256. +                   if (basic_block_head[block] == insn)
  1257. +                     basic_block_head[block] = new_insn;
  1258. +                   if (file)
  1259. +                     {
  1260. +                     fprintf (file, "insn %d was added ",
  1261. +                            INSN_UID (new_insn));
  1262. +                     fprintf (file, "before insn %d\n",
  1263. +                                INSN_UID (insn));
  1264. +                     }
  1265. +                   /* move the insn's LOG_LINKS to new_insn */
  1266. +                   LOG_LINKS (new_insn) = LOG_LINKS (insn);
  1267. +                   LOG_LINKS (insn) = 0;
  1268. +                   /* move all relevant REG_DEAD notes to
  1269. +                      new_insn */
  1270. +                   for (note = REG_NOTES (insn);
  1271. +                        note;
  1272. +                        note = XEXP (note, 1))
  1273. +                     {
  1274. +                       if (REG_NOTE_KIND (note) == REG_DEAD)
  1275. +                     {
  1276. +                       register int regno 
  1277. +                         = REGNO (XEXP (note, 0));
  1278. +                       if (GET_RTX_LENGTH (
  1279. +                           GET_CODE (insn_src)) < 2
  1280. +                             || GET_CODE (XEXP (insn_src,
  1281. +                                    1 - mem_loc))
  1282. +                                    != REG
  1283. +                            || REGNO (XEXP (insn_src,
  1284. +                              1 - mem_loc))
  1285. +                             != regno)
  1286. +                         {
  1287. +                               
  1288. +                           /* this note does not refer to
  1289. +                              the register that will be
  1290. +                              used from now on within
  1291. +                              insn, thus we move it to
  1292. +                             new_insn. */
  1293. +                           remove_note (insn, note);
  1294. +                           mhp = ®no_holds_mem[regno];
  1295. +                           REG_NOTES (new_insn) =
  1296. +                           gen_rtx (EXPR_LIST,
  1297. +                             REG_DEAD,
  1298. +                             XEXP (note, 0),
  1299. +                             REG_NOTES(new_insn));
  1300. +                           mhp -> insn_dead = new_insn;
  1301. +                           SET_HARD_REG_BIT
  1302. +                                (free_regs,
  1303. +                                 REGNO (XEXP (note, 0)));
  1304. +                         }
  1305. +                     }  /* if (REG_NOTE_KIND (note) == REG_DEAD) */
  1306. +                     }  /* for (note = REG_NOTES (insn);
  1307. +                                note;
  1308. +                                note = XEXP (note, 1)) */
  1309. +                 }  /* if (! skip_load_f) */
  1310. +                       else
  1311. +                 /* we use an already loaded register */
  1312. +                 {
  1313. +                   /* since we use a load for a possibly 
  1314. +                      previously riscified insn, we should
  1315. +                      unmark the insns created for that insn,
  1316. +                      so that recombine will not try to
  1317. +                      delete its load */
  1318. +                   mhp = ®no_holds_mem[regno];
  1319. +                   if (mhp -> insn_dead)
  1320. +                     {
  1321. +                       /* we should reset the RISC flag on
  1322. +                          the insns added for risc, so that
  1323. +                          they will not be recombined later
  1324. +                       */
  1325. +                       t_insn = PREV_INSN (mhp -> insn_dead);
  1326. +                       while (t_insn && RTX_IS_RISC_P (t_insn))
  1327. +                     {
  1328. +                        RTX_IS_RISC_P (t_insn) = 0;
  1329. +                        t_insn = PREV_INSN (t_insn);
  1330. +                     }
  1331. +                           remove_death (regno, mhp->insn_dead);
  1332. +                         }  /* if (mhp -> insn_load) */
  1333. +                   if (file)
  1334. +                     {
  1335. +                       fprintf (file, "insn %d: changed mem ",
  1336. +                                INSN_UID (insn));
  1337. +                       fprintf (file, "operand with already "
  1338. +                                "loaded register %d\n",
  1339. +                                regno);
  1340. +                     }
  1341. +                 }
  1342. +                       /* in the case the memory operand was also the
  1343. +                  insn's destination, we should add an insn
  1344. +                  to store the result, now stored in
  1345. +                  new_reg. */
  1346. +                       if (memory_dest_changed)
  1347. +                     {
  1348. +                       /* Since memory destination was replaced by
  1349. +                          a register, its contents is clobbered */
  1350. + #if 0
  1351. +                   regno_holds_mem[regno].mem = 0;
  1352. + #endif
  1353. +                   bzero (®no_holds_mem[regno],
  1354. +                          sizeof (MEM_HOLDER));
  1355. +                   update_entries (new_reg);
  1356. +                   new_insn = make_insn_raw (pat);
  1357. +                   RTX_IS_RISC_P (new_insn) = 1;
  1358. +                   add_insn_after (new_insn,
  1359. +                               PREV_INSN (insn));
  1360. +                   if (skip_load_f
  1361. +                       && basic_block_head[block] == insn)
  1362. +                     basic_block_head[block] = new_insn;
  1363. +                   if (file
  1364. +                       && ! skip_load_f)
  1365. +                     {
  1366. +                       fprintf (file, "insn %d was also ",
  1367. +                            INSN_UID (new_insn));
  1368. +                       fprintf (file, "added before insn ");
  1369. +                       fprintf (file, "%d\n",
  1370. +                               INSN_UID (insn));
  1371. +                     }
  1372. +                   else if (file)
  1373. +                     {
  1374. +                     fprintf (file,
  1375. +                              "insn %d was added before "
  1376. +                              "insn %d, load was saved\n",
  1377. +                              INSN_UID (new_insn),
  1378. +                              INSN_UID (insn));
  1379. +                    }
  1380. +                   /* change insn to be just a store insn */
  1381. +                   PATTERN (insn) = gen_rtx (SET,
  1382. +                                 VOIDmode,
  1383. +                                 mem_opr,
  1384. +                                 new_reg);
  1385. +                   /* now we might find that a previous
  1386. +                      store is redundant... */
  1387. +                   if ((i = remove_redundant_store (mem_opr,
  1388. +                                    block))
  1389. +                        && file)
  1390. +                     {
  1391. +                     fprintf (file,
  1392. +                              "insn %d: caused deletion of "
  1393. +                              "a redundant store: %d\n",
  1394. +                              INSN_UID (insn),
  1395. +                              i);
  1396. +                     }
  1397. +                   /* now we actually changed the insn's
  1398. +                      code, so we erase the current one and
  1399. +                      we let next phases (probably sched2) to
  1400. +                      update this code. */
  1401. +                   INSN_CODE (insn) = -1;
  1402. +                   if (! skip_load_f)
  1403. +                     {
  1404. +                       /* add the last_new_insn to the new_insn's
  1405. +                      dependency list */
  1406. +                       link = rtx_alloc (INSN_LIST);
  1407. +                       PUT_REG_NOTE_KIND (link, 0);
  1408. +                       XEXP (link, 0) = PREV_INSN (new_insn);
  1409. +                       XEXP (link, 1) = LOG_LINKS (new_insn);
  1410. +                       LOG_LINKS (new_insn) = link;
  1411. +                     }
  1412. +                 }    /* if (memory_dest_changed) */
  1413. +                       /* add the new_insn to the insn's dependency
  1414. +                  list */
  1415. +                       if (! skip_load_f
  1416. +                   || memory_dest_changed)
  1417. +                 {
  1418. +                   link = rtx_alloc (INSN_LIST);
  1419. +                   PUT_REG_NOTE_KIND (link, 0);
  1420. +                   XEXP (link, 0) = new_insn;
  1421. +                   XEXP (link, 1) = LOG_LINKS (insn);
  1422. +                   LOG_LINKS (insn) = link;
  1423. +                 }
  1424. +                   /* Add a REG_DEAD note to the last insn to
  1425. +                      indicate that the used register is no
  1426. +                      longer needed.
  1427. +                      This is not needed for this phase since we
  1428. +                      do not remove this register from the free
  1429. +                      register list (we just mark it to indicate
  1430. +                      that next allocation of free register, will
  1431. +                      not return it again, so that dependency
  1432. +                      between adjacent insns will be as less as
  1433. +                      possible). */
  1434. +                   if (GET_CODE (insn_dest) != REG
  1435. +                   || REGNO (insn_dest) != REGNO (new_reg))
  1436. +                       {
  1437. +                 REG_NOTES (insn) 
  1438. +                   = gen_rtx (EXPR_LIST,
  1439. +                          REG_DEAD,
  1440. +                          new_reg, 
  1441. +                          REG_NOTES (insn));
  1442. +                       }
  1443. + #ifdef REGISTER_CONSTRAINTS
  1444. +                     }  /* the replacement is valid */
  1445. + #endif
  1446. +             }  /* if (regno != FIRST_PSEUDO_REGISTER) */
  1447. +               else if (file)
  1448. +             {
  1449. +                     fprintf (file, "insn %d: No suitable free hard",
  1450. +                                          INSN_UID (insn));
  1451. +                     fprintf (file, " register found for risc\n");
  1452. +             }
  1453. +             }  /* if (mem_opr) */
  1454. +         }  /* if (GET_CODE (pat) == SET) */
  1455. +             }  /* if (GET_CODE(insn) == INSN) */
  1456. +       if (GET_CODE (insn) == CODE_LABEL)
  1457. +         bzero (regno_holds_mem, sizeof regno_holds_mem);
  1458. +       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
  1459. +         {
  1460. +           if (GET_CODE (insn) == CALL_INSN)
  1461. +             {
  1462. +            /* all call clobbered registers are now free */
  1463. +            for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
  1464. +              if (call_used_regs[j])
  1465. +                   SET_HARD_REG_BIT (free_regs, j);
  1466. +             }
  1467. +           update_free_regs (PATTERN (insn));
  1468. +           update_regno_holds_mem (insn, PATTERN (insn));
  1469. +           /* add each dead register to the free_regs set */
  1470. +           /* mark each dead regno in the regno_holds_mem array */
  1471. +           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
  1472. +             {
  1473. +           if ((REG_NOTE_KIND (note) == REG_DEAD
  1474. +                || REG_NOTE_KIND (note) == REG_UNUSED)
  1475. +               && GET_CODE (XEXP (note, 0)) == REG)
  1476. +             {
  1477. +               regno = REGNO (XEXP (note, 0));
  1478. +               nregs = 
  1479. +                 HARD_REGNO_NREGS (regno, GET_MODE (XEXP (note, 0)));
  1480. +   
  1481. +               for (i = 0; i < nregs; i++)
  1482. +                 SET_HARD_REG_BIT (free_regs, regno + i);
  1483. +               regno_holds_mem[regno].insn_dead = insn;
  1484. +             }
  1485. +         }
  1486. +           if ((note = find_reg_note (insn, REG_WAS_0, 0)))
  1487. +             {
  1488. +               rtx set;
  1489. +               set = single_set (insn);
  1490. +               if (set == NULL 
  1491. +               || GET_CODE (SET_DEST (set)) == REG)
  1492. +                 { /* Since reg may have been reused.  */
  1493. +               remove_note (insn, note);
  1494. +                 }
  1495. +             }
  1496. +         }  /* if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') */
  1497. +     }  /* for (insn = basic_block_head[block]; */
  1498. +     }  /* for (block = 0; block < n_basic_blocks; block++) */
  1499. +     /* mark each insn with it's next nonnote insn so that recombine can work */
  1500. +     {
  1501. +       t_insn = f;
  1502. +       while (t_insn)
  1503. +         {
  1504. +           if (GET_CODE (t_insn) == INSN)
  1505. +             ORG_NEXT_INSN (t_insn) = next_nonnote_insn (t_insn);
  1506. +           t_insn = NEXT_INSN (t_insn);
  1507. +         }
  1508. +     }
  1509. + }                /* memory_simplify (file, f) */
  1510. + static void
  1511. + dump_free_registers (file)
  1512. +      FILE *file;
  1513. + {
  1514. +   register int regno;
  1515. +   fprintf (file, "Free registers now are: ");
  1516. +   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  1517. +     if (TEST_HARD_REG_BIT (free_regs, regno))
  1518. +       {
  1519. +     fprintf (file, " %d", regno);
  1520. +       }
  1521. +   fprintf (file, "\n");
  1522. + }
  1523. + /*  Finds a free register that is able to contain a value of mode MODE.
  1524. +  *  Returns the number of the hard register (or the first hard register, in
  1525. +  *  case of multi-register value) found, if such exists, and mark it in the
  1526. +  *  regs_ever_live array. Otherwise returns  FIRST_PSEUDO_REGISTER.
  1527. +  */
  1528. + int
  1529. + find_free_reg (mode)
  1530. +      enum machine_mode mode;
  1531. + {
  1532. +   register int regno;
  1533. +   /* record last_reg retunrned. Try next find form this reg on. */
  1534. +   static int last_reg;
  1535. +   int not_desired;        /* is this the "not-desired" regset: i.e. are we going to
  1536. +             * take the register from those who are not "safe" within
  1537. +             * a function (their values is promised not to be altered).
  1538. +             */
  1539. +   int second_half;        /* is this the second half of the "round-robin" search */
  1540. + #ifdef IS_RISC_MODE
  1541. +   if (!IS_RISC_MODE (mode))
  1542. +     {
  1543. +       return (FIRST_PSEUDO_REGISTER);
  1544. +     }
  1545. + #endif
  1546. +   /* we handle only DImode SImode, HImode and QImode */
  1547. +   switch (mode)
  1548. +     {
  1549. +     case DImode:
  1550. +     case SImode:
  1551. +     case HImode:
  1552. +     case QImode:
  1553. +       /* Try to find the register among those whos value is not "safe"
  1554. +        * first.
  1555. +        */
  1556. +       for (not_desired = 0; not_desired < 2; not_desired++)
  1557. +     {
  1558. +       int last_reg_scanned = 0;
  1559. +       /* implement a "round-robin" algorithm for register scanning.
  1560. +          fisrt look from the last_reg and on, and then from 0 to
  1561. +          last_reg. */
  1562. +          
  1563. +       for (regno = (last_reg + 1) % FIRST_PSEUDO_REGISTER;
  1564. +            ! last_reg_scanned;
  1565. +            regno = (regno + 1) % FIRST_PSEUDO_REGISTER)
  1566. +         {
  1567. +           register int i, nregs = HARD_REGNO_NREGS (regno, mode);
  1568. +           register int found = 1;
  1569. +           last_reg_scanned = last_reg == regno;
  1570. +           for (i = 0; i < nregs; i++)
  1571. +             {
  1572. +               if (! not_desired
  1573. +               && (! call_used_regs[regno + i]
  1574. +               || TEST_HARD_REG_BIT (not_recommended_regs,
  1575. +                           regno + i)))
  1576. +             found = 0;
  1577. +               else if (! fixed_regs[regno + i]
  1578. +                        && TEST_HARD_REG_BIT (free_regs, regno + i)
  1579. +                        && HARD_REGNO_MODE_OK (regno + i, mode)
  1580. + #ifdef ELIMINABLE_REGS
  1581. +                && (! frame_pointer_needed
  1582. +                    || regno != FRAME_POINTER_REGNUM)
  1583. + #endif
  1584. +                /* allow only registers that lived before this
  1585. +                   phase to take part. This might reduce the number
  1586. +                   of registers available, but otherwise some
  1587. +                   problems may occur due to use of a register that
  1588. +                   need to be pushed at the the function prologue,
  1589. +                   thus corrupting the calculations of stack slots
  1590. +                   previously performed at the reload phase. */
  1591. +                && (call_used_regs[regno + i]
  1592. +                    || regs_ever_live[regno + i])
  1593. +               )
  1594. +             continue;
  1595. +           else
  1596. +             found = 0;
  1597. +         }  /* for (i = 0; i < nregs; i++) */
  1598. +           if (found)
  1599. +         {
  1600. +           /* save regno for the next invokation */
  1601. +           last_reg = regno + nregs - 1;
  1602. +           return (regno);
  1603. +         }
  1604. +         } /* for (regno = (last_reg + 1) % FIRST_PSEUDO_REG;
  1605. +              regno != last_reg;
  1606. +              regno = (regno + 1) % FIRST_PSEUDO_REG) */
  1607. +     }  /* for (not_desired = 0; not_desired < 2; not_desired ++) */
  1608. +       break;
  1609. +     }  /* switch (mode) */
  1610. +   return (FIRST_PSEUDO_REGISTER);
  1611. + }
  1612. + /* Updates the free_regs regset according the contents of PAT */
  1613. + void
  1614. + update_free_regs (rtx pat)
  1615. + {
  1616. +   register int i, regno, nregs;
  1617. +   register j;
  1618. +   register char *fmt;
  1619. +   register RTX_CODE code = GET_CODE (pat);
  1620. +   switch (code)
  1621. +     {
  1622. +       case SET:
  1623. +       case USE:
  1624. +       case CLOBBER:
  1625. +         if (GET_CODE (SET_DEST (pat)) == REG)
  1626. +           {
  1627. +             regno = REGNO (SET_DEST (pat));
  1628. +             nregs = HARD_REGNO_NREGS (regno,
  1629. +                                    GET_MODE (SET_DEST (pat)));
  1630. +             if (GET_CODE (pat) == SET
  1631. +                 || GET_CODE (pat) == USE)
  1632. +               for (i = 0; i < nregs; i++)
  1633. +                 CLEAR_HARD_REG_BIT (free_regs, regno + i);
  1634. + #if 0
  1635. +             else /* GET_CODE (pat) == CLOBBER */
  1636. +               for (i = 0; i < nregs; i++)
  1637. +                 SET_HARD_REG_BIT (free_regs, regno + i);
  1638. + #endif
  1639. +           }
  1640. +         else if (GET_CODE (SET_DEST (pat)) == SUBREG
  1641. +                  && GET_CODE (SUBREG_REG (SET_DEST (pat))) == REG)
  1642. +           {
  1643. +             regno = REGNO (SUBREG_REG (SET_DEST (pat))) 
  1644. +                          + SUBREG_WORD (SET_DEST (pat));
  1645. +             nregs = HARD_REGNO_NREGS (regno,
  1646. +                                    GET_MODE (SET_DEST (pat)));
  1647. +             if (GET_CODE (pat) == SET
  1648. +                 || GET_CODE (pat) == USE)
  1649. +               for (i = 0; i < nregs; i++)
  1650. +                 CLEAR_HARD_REG_BIT (free_regs, regno + i);
  1651. +           }
  1652. +         break;
  1653. +       case ADDR_VEC:
  1654. +       case CALL:
  1655. +       case HIGH:
  1656. +       case CONST_INT:
  1657. +       case CONST:
  1658. +       case CONST_DOUBLE:
  1659. +       case SYMBOL_REF:
  1660. +       case LABEL_REF:
  1661. +       case PC:
  1662. +       case CC0:
  1663. +       case REG:
  1664. +         /* do nothing */
  1665. +         return;
  1666. +    }  /* switch (GET_CODE (pat)) */
  1667. +   fmt = GET_RTX_FORMAT (code);
  1668. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  1669. +     if (fmt[i] == 'e')
  1670. +       {
  1671. +         if( XEXP (pat, i))
  1672. +           update_free_regs (XEXP (pat, i));
  1673. +       }
  1674. +     else if (fmt[i] == 'E' || fmt[i] == 'V')
  1675. +       {
  1676. +     for (j = 0; j < XVECLEN (pat, i); j++)
  1677. +       update_free_regs (XVECEXP (pat, i, j));
  1678. +       }
  1679. + }
  1680. + #if 0
  1681. + /* Returns a hard register regno, if the contents of entry regno in
  1682. +    last_reloads array equals to MEM, FIRST_PSEUDO_REGISTER otherwise. */
  1683. + static int
  1684. + find_last_reload (rtx mem)
  1685. + {
  1686. +   register int regno;
  1687. +   
  1688. +   if (GET_CODE (mem) != MEM)
  1689. +     abort ();
  1690. +   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  1691. +     if (rtx_equal_p (LAST_RELOAD (regno), mem))
  1692. +       return (regno);
  1693. +   return (FIRST_PSEUDO_REGISTER);
  1694. + }
  1695. + #endif
  1696. + /* Returns regno of a free register holding MEM, or FIRST_PSEUDO_REGISTER if
  1697. +    not exist such register. */
  1698. + static int
  1699. + find_regno_holds_mem (rtx mem, enum machine_mode mode)
  1700. + {
  1701. +   int i, is_const;
  1702. +   MEM_HOLDER *mhp;
  1703. +   is_const = GET_CODE (mem) == CONST_INT;
  1704. +   
  1705. +   for (mhp = regno_holds_mem;
  1706. +        mhp < regno_holds_mem + FIRST_PSEUDO_REGISTER;
  1707. +        mhp++)
  1708. +     {
  1709. +       if (mhp->mem && GET_CODE (mhp->insn_load) == NOTE)
  1710. +         { /* was deleted */
  1711. +           mhp->insn_load = NULL;
  1712. +           mhp->mem = NULL;
  1713. +           mhp->insn_dead = NULL;
  1714. +         }
  1715. +       if (mhp->insn_store && GET_CODE (mhp->insn_store) == NOTE)
  1716. +         { /* was deleted */
  1717. +           mhp->insn_store = NULL;
  1718. +         }
  1719. + #if 0
  1720. +       if ((mhp->insn_load 
  1721. +            && mhp->mem
  1722. + #endif
  1723. +       if ((mhp->mem
  1724. +            && GET_CODE (mhp -> mem) == GET_CODE (mem)
  1725. +            && (is_const 
  1726. +                 ? rtx_equal_p ( (mhp -> mem), (mem))
  1727. +                 : rtx_equal_p (XEXP (mhp -> mem, 0), XEXP (mem, 0)))
  1728. +            && HARD_REGNO_MODE_OK (mhp - regno_holds_mem, mode)
  1729. +            && GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (mhp -> insn_load))))
  1730. +                >= GET_MODE_SIZE (mode))
  1731. +       || (mhp -> mem
  1732. +           && mhp -> insn_store
  1733. +               && GET_MODE_SIZE (GET_MODE (SET_SRC (PATTERN (mhp -> insn_store))))
  1734. +                    >= GET_MODE_SIZE (mode)
  1735. +               && GET_CODE (SET_DEST ( PATTERN (mhp -> insn_store))) 
  1736. +                    == GET_CODE (mem)
  1737. +               && HARD_REGNO_MODE_OK (mhp - regno_holds_mem, mode)
  1738. +               && (is_const
  1739. +                   ? rtx_equal_p (SET_DEST ( PATTERN (mhp -> insn_store)), 
  1740. +                                  mem)
  1741. +                   : rtx_equal_p (XEXP (SET_DEST (PATTERN (mhp -> insn_store)),
  1742. +                                  0),
  1743. +                                  XEXP (mem, 0)))))
  1744. +         return (mhp - regno_holds_mem);
  1745. +     }
  1746. +   return FIRST_PSEUDO_REGISTER;
  1747. + }  /* find_regno_holds_mem (rtx mem) */
  1748. + /* Updates the regno_holds_mem array as required from pat */
  1749. + static void
  1750. + update_regno_holds_mem (rtx insn, rtx pat)
  1751. + {
  1752. +   register int i, j, regno, nregs;
  1753. +   MEM_HOLDER *mhp;
  1754. +   rtx set_src, set_dest;
  1755. +   register char *fmt;
  1756. +   register RTX_CODE code = GET_CODE (pat);
  1757. +   if (GET_CODE (insn) == JUMP_INSN)
  1758. +     {
  1759. +       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  1760. +         regno_holds_mem[i].insn_store = 0;
  1761. +       return;
  1762. +     }
  1763. +   switch (GET_CODE (pat))
  1764. +     {
  1765. +       case SET:
  1766. +         set_src = SET_SRC (pat);
  1767. +         set_dest = SET_DEST (pat);
  1768. +         if (GET_CODE (set_dest) == REG)
  1769. +           {
  1770. +             regno = REGNO (set_dest);
  1771. +             nregs = HARD_REGNO_NREGS (regno, GET_MODE (set_dest));
  1772. +             mhp = ®no_holds_mem[regno];
  1773. +             if (nregs == 1
  1774. +                 && (GET_CODE (set_src) == MEM
  1775. +                     && !MEM_VOLATILE_P (set_src)
  1776. +                     && GET_CODE (XEXP (set_src, 0)) != PRE_INC
  1777. +                     && GET_CODE (XEXP (set_src, 0)) != PRE_DEC
  1778. +                     && GET_CODE (XEXP (set_src, 0)) != POST_INC
  1779. +                     && GET_CODE (XEXP (set_src, 0)) != POST_DEC)
  1780. +                    || GET_CODE (set_src) == CONST_INT)
  1781. +               {
  1782. +                 mhp -> mem = set_src;
  1783. +                 mhp -> insn_load = insn;
  1784. +                 mhp -> insn_store = mhp -> insn_dead = 0;
  1785. +               }
  1786. +             else
  1787. +               {
  1788. +                 for (; mhp < ®no_holds_mem[regno] + nregs; mhp++)
  1789. +                   {
  1790. +                     bzero (mhp, sizeof (MEM_HOLDER));
  1791. +                   }
  1792. +               }
  1793. +             if (nregs == 1)
  1794. +               {
  1795. +                 /* since we set a register, each mem using this reg is not valid
  1796. +                    any more */
  1797. +                 update_entries (set_dest);
  1798. +               }
  1799. +             else
  1800. +               {
  1801. +                 /* memory holds more than one register. This is a simplification
  1802. +                    Actually we should zero only those register entries which are
  1803. +                    relevant for nregs... */
  1804. +                 bzero (regno_holds_mem, sizeof regno_holds_mem);
  1805. +                 break;
  1806. +               }
  1807. +             update_regno_holds_mem (insn, set_src);
  1808. +           }
  1809. +         else if (GET_CODE (set_dest) == SUBREG)
  1810. +           {
  1811. +             if (GET_CODE (SUBREG_REG (set_dest)) == REG)
  1812. +               {
  1813. +                 regno = REGNO (SUBREG_REG (set_dest)) + SUBREG_WORD (set_dest);
  1814. +                 nregs 
  1815. +                   = HARD_REGNO_NREGS (regno, GET_MODE (SUBREG_REG (set_dest)));
  1816. +                 mhp = ®no_holds_mem[regno];
  1817. +                 for (; mhp < ®no_holds_mem[regno] + nregs; mhp++)
  1818. +                   {
  1819. +                     bzero (mhp, sizeof (MEM_HOLDER));
  1820. +                   }
  1821. +                 if (nregs == 1)
  1822. +                   {
  1823. +                     update_entries (SUBREG_REG (set_dest));
  1824. +                   }
  1825. +                 else
  1826. +                   {
  1827. +                     /* memory holds more than one register. This is a simplification.
  1828. +                        Actually we should zero only those register entries which are
  1829. +                        relevant for nregs... */
  1830. +                     bzero (regno_holds_mem, sizeof regno_holds_mem);
  1831. +                   }
  1832. +                 update_regno_holds_mem (insn, set_src);
  1833. +                 return;
  1834. +               }
  1835. +             else /* subreg of mem */
  1836. +               {
  1837. +             for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  1838. +               regno_holds_mem[i].mem = 0;
  1839. +                 update_regno_holds_mem (insn, XEXP (XEXP (set_dest, 0), 0));
  1840. +                 update_regno_holds_mem (insn, set_src);
  1841. +                 return;
  1842. +               }
  1843. +           }
  1844. +         else if (GET_CODE (set_dest) == MEM)
  1845. +           {
  1846. +         MEM_HOLDER save_mh;
  1847. +         int is_push = 0;
  1848. +         mhp = 0;
  1849. +             if ((GET_CODE (set_src) == REG
  1850. +                  || GET_CODE (set_src) == CONST_INT)
  1851. +                 && push_operand (set_dest, Pmode))
  1852. +               { /* A push only ruins memory references based on stack_pointer */
  1853. +                 is_push = 1;
  1854. +               }
  1855. +             else if (GET_CODE (set_src) == REG
  1856. +                 /* We might want to add the possibility of SUBREG, isn't it? */
  1857. +                 && !MEM_VOLATILE_P (set_dest)
  1858. +                 && GET_CODE (XEXP (set_dest, 0)) != PRE_INC
  1859. +                 && GET_CODE (XEXP (set_dest, 0)) != PRE_DEC
  1860. +                 && GET_CODE (XEXP (set_dest, 0)) != POST_INC
  1861. +                 && GET_CODE (XEXP (set_dest, 0)) != POST_DEC)
  1862. +               {
  1863. +                 register int regno = REGNO (set_src);
  1864. +                 register int nregs = HARD_REGNO_NREGS (regno,
  1865. +                                        GET_MODE (set_src));
  1866. +                 if (nregs == 1)
  1867. +                   {
  1868. +                     mhp = ®no_holds_mem[regno];
  1869. +                     save_mh = *mhp;
  1870. +                   }
  1871. +               }
  1872. +             else if (GET_CODE (set_src) != REG)
  1873. +               update_regno_holds_mem (insn, set_src);
  1874. +             if (!is_push)
  1875. +               {
  1876. +                 MEM_HOLDER *p = regno_holds_mem;
  1877. +                 rtx store_pat;
  1878. +                 
  1879. +             for (; p < regno_holds_mem + FIRST_PSEUDO_REGISTER; p++)
  1880. +               {
  1881. +                 if (p -> mem)
  1882. +                   {
  1883. +                     if (GET_CODE (p -> mem) == MEM
  1884. +                         && true_dependence (set_dest, p -> mem))
  1885. +                       {
  1886. +                         p -> mem = 0;
  1887. +                       }
  1888. +                   }
  1889. +                 if (p -> insn_store
  1890. +                     && (store_pat = PATTERN (p -> insn_store))
  1891. +                     && GET_CODE (SET_DEST (store_pat)) == MEM
  1892. +                     && true_dependence (set_dest,
  1893. +                                     SET_DEST (store_pat)))
  1894. +                   {
  1895. +                     /* insn_store is not valid any more */
  1896. +                     p -> insn_store = 0;
  1897. +                   }
  1898. +               }
  1899. +           }
  1900. +             if (mhp)
  1901. +               {
  1902. +                 /* restore the relevant entry */
  1903. +         *mhp = save_mh;
  1904. +         mhp -> insn_store = insn;
  1905. +         /* if there was no load, we can consider this insn as if it is a
  1906. +            load */
  1907. +         if (! mhp -> insn_load || GET_CODE (mhp -> insn_load) == NOTE)
  1908. +           {
  1909. +             mhp -> insn_load = insn;
  1910. +             mhp -> mem = set_dest;
  1911. +           }
  1912. +           }
  1913. +               update_regno_holds_mem (insn, XEXP (set_dest, 0));
  1914. +           }
  1915. +         else
  1916. +           {
  1917. +             update_regno_holds_mem (insn, set_dest);
  1918. +             update_regno_holds_mem (insn, set_src);
  1919. +           }
  1920. +         return;
  1921. +       case CLOBBER:
  1922. +     set_dest = SET_DEST (pat);
  1923. +         if (GET_CODE (set_dest) == REG)
  1924. +           {
  1925. +             register int regno = REGNO (set_dest);
  1926. +             register int nregs = HARD_REGNO_NREGS (regno,
  1927. +                                    GET_MODE (set_dest));
  1928. +         if (nregs == 1)
  1929. +           {
  1930. +             bzero (®no_holds_mem[regno], sizeof (MEM_HOLDER));
  1931. +             update_entries (set_dest);
  1932. +               }
  1933. +             else
  1934. +               /* memory holds more than one register. This is a simplification.
  1935. +                  Actually we should zero only those register entries which are
  1936. +                  relevant for nregs... */
  1937. +               bzero (regno_holds_mem, sizeof regno_holds_mem);
  1938. +           }
  1939. +         else if (GET_CODE (set_dest) == SUBREG)
  1940. +           {
  1941. +             regno = REGNO (SUBREG_REG (set_dest));
  1942. +             nregs = HARD_REGNO_NREGS (regno, GET_MODE (XEXP (set_dest, 0)));
  1943. +             mhp = ®no_holds_mem[regno];
  1944. +             for (; mhp < ®no_holds_mem[regno] + nregs; mhp++)
  1945. +               {
  1946. +                 bzero (mhp, sizeof (MEM_HOLDER));
  1947. +               }
  1948. +             if (nregs == 1)
  1949. +               {
  1950. +                 update_entries (XEXP (set_dest, 0));
  1951. +               }
  1952. +             else
  1953. +               {
  1954. +                 /* memory holds more than one register. This is a simplification.
  1955. +                    Actually we should zero only those register entries which are
  1956. +                    relevant for nregs... */
  1957. +                 bzero (regno_holds_mem, sizeof regno_holds_mem);
  1958. +               }
  1959. +             return;
  1960. +           }
  1961. +         else if (GET_CODE (set_dest) == MEM)
  1962. +           for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  1963. +             {
  1964. +               /* the mem field indicates that this regno is no more valid for
  1965. +                  replacement in loads. Note that this regno might be valid for
  1966. +                  redundant store, or even replace loads with memory to which
  1967. +                  this reg was writing in the insn_store, and in such case we
  1968. +                  would like to reset the risc flags on all insns, from insn_load
  1969. +                  to insn_dead. This is why we don't reset here insn_load and
  1970. +                  insn_dead. */
  1971. +           if (regno_holds_mem[i].mem
  1972. +               && GET_CODE (regno_holds_mem[i].mem) == MEM
  1973. +               && true_dependence (set_dest, regno_holds_mem[i].mem))
  1974. +                 regno_holds_mem[i].mem = 0;
  1975. +             }
  1976. +         else
  1977. +           {
  1978. +             fprintf (stderr,
  1979. +                      "unpredicted case caused reset of regno_holds_mem:\n");
  1980. +             fprintf (stderr, "pattern:\n");
  1981. +             debug_rtx (pat);
  1982. +             fprintf (stderr, "insn:\n");
  1983. +         debug_rtx (insn);
  1984. +         bzero (regno_holds_mem, sizeof regno_holds_mem);
  1985. +       }
  1986. +         return;
  1987. +       case CALL:
  1988. +         /* since we cannot know what writes to memory in the function call,
  1989. +            we must not use the information in regno_holds_mem anymore */
  1990. +     bzero (regno_holds_mem, sizeof regno_holds_mem);
  1991. +         return;
  1992. +       case PRE_DEC:
  1993. +       case PRE_INC:
  1994. +       case POST_DEC:
  1995. +       case POST_INC:
  1996. +         if (GET_CODE (XEXP (pat, 0)) == REG)
  1997. +           {
  1998. +             bzero (®no_holds_mem[REGNO (XEXP (pat,0))], sizeof (MEM_HOLDER));
  1999. +         update_entries (XEXP (pat, 0));
  2000. +           }
  2001. +         else
  2002. +           {
  2003. +             update_regno_holds_mem (insn, XEXP (pat, 0));
  2004. +           }
  2005. +         return;
  2006. +       case MEM:
  2007. +         /* there is a use of a memory in this insn, we cannot trust the
  2008. +            insn_store data anymore */
  2009. +         for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  2010. +           {
  2011. +             regno_holds_mem[i].insn_store = 0;
  2012. +             if (regno_holds_mem[i].insn_load == NULL)
  2013. +               {
  2014. +                 regno_holds_mem[i].insn_dead = 0;
  2015. +                 regno_holds_mem[i].mem = NULL;
  2016. +               }
  2017. +           }
  2018. +         update_regno_holds_mem (insn, XEXP (pat, 0));
  2019. +         return;
  2020. +       case USE:
  2021. +         update_regno_holds_mem (insn, SET_DEST (pat));
  2022. +         return;
  2023. +     case HIGH:
  2024. +     case CONST_INT:
  2025. +     case CONST:
  2026. +     case CONST_DOUBLE:
  2027. +     case SYMBOL_REF:
  2028. +     case LABEL_REF:
  2029. +     case PC:
  2030. +     case CC0:
  2031. +     case REG:
  2032. +     /*case SUBREG:*/
  2033. +         /* do nothing */
  2034. +         return;
  2035. +   }  /* switch (GET_CODE (pat)) */
  2036. +   fmt = GET_RTX_FORMAT (code);
  2037. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  2038. +     if (fmt[i] == 'e')
  2039. +       {
  2040. +         if( XEXP (pat, i))
  2041. +           update_regno_holds_mem (insn, XEXP (pat, i));
  2042. +       }
  2043. +     else if (fmt[i] == 'E' || fmt[i] == 'V')
  2044. +       {
  2045. +     for (j = 0; j < XVECLEN (pat, i); j++)
  2046. +       update_regno_holds_mem (insn, XVECEXP (pat, i, j));
  2047. +       }
  2048. + }  /* update_regno_holds_mem (rtx pat) */
  2049. + /* Invalidates entries of memory mentioning REG in their memories, and the
  2050. +    entry of the appropriate REG */
  2051. + static void
  2052. + update_entries (rtx reg)
  2053. + {
  2054. +   register MEM_HOLDER *mhp = regno_holds_mem;
  2055. +   register int regno = REGNO (reg);
  2056. +   for (; mhp < regno_holds_mem + FIRST_PSEUDO_REGISTER; mhp++)
  2057. +     {
  2058. +       if (mhp->mem && reg_overlap_mentioned_p (reg, mhp->mem))
  2059. +         {
  2060. +           if (mhp->insn_store && mhp->insn_store != mhp->insn_load)
  2061. +             {
  2062. +               mhp -> insn_load = mhp -> insn_store;
  2063. +               mhp -> mem = SET_DEST (PATTERN (mhp -> insn_load));
  2064. +               mhp -> insn_dead = 0;
  2065. +             }
  2066. +           else
  2067. +             bzero (mhp, sizeof (MEM_HOLDER));
  2068. +         }
  2069. +       if (mhp -> insn_store && GET_CODE (mhp -> insn_store) == INSN
  2070. +           /* insn_store can be deleted by redundant store elimination */
  2071. +           && reg_overlap_mentioned_p (reg, 
  2072. +                                       SET_DEST (PATTERN (mhp->insn_store))))
  2073. +         {
  2074. +           if (mhp->insn_load == mhp->insn_store)
  2075. +            {
  2076. +               bzero (mhp, sizeof (MEM_HOLDER));
  2077. +            }
  2078. +           else
  2079. +            {
  2080. +              mhp -> insn_store = 0;
  2081. +            }
  2082. +         }
  2083. +     }  /* for (; mhp < regno_holds_mem + FIRST_PSEUDO_REGISTER; mhp++) */
  2084. + }  /* update_entries (rtx reg) */
  2085. + /* for each regno found to be non-free (is used or set) from (and including)
  2086. +    FIRST, to LAST, clears the appropriate bit in HARD_REG_SET pointed to by
  2087. +    FREE. */
  2088. +    
  2089. + void
  2090. + find_free_regs_between (free, first, last)
  2091. +     HARD_REG_SET *free;
  2092. +     rtx first;
  2093. +     rtx last;
  2094. + {
  2095. +   rtx insn, pat;
  2096. +   char *funcname = "find_free_regs_between";
  2097. +   register int i;
  2098. +   if (! first)
  2099. +     abort ();
  2100. +   if (! last)
  2101. +     abort ();
  2102. +   insn = first;
  2103. +   while (insn
  2104. +          && insn != last)
  2105. +     {
  2106. +       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
  2107. +         {
  2108. +           if (GET_CODE (insn) == CALL_INSN)
  2109. +             {
  2110. +               /* we should reset all regs clobbered by a call */
  2111. +               for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  2112. +             if (call_used_regs[i])
  2113. +           CLEAR_HARD_REG_BIT (*free, i);
  2114. +         }
  2115. +       else  /* GET_RTX_CLASS (GET_CODE (insn)) != 'i' */
  2116. +         {
  2117. +           pat = PATTERN (insn);
  2118. +               for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  2119. +         if (INSN_SETS_REGNO (insn, i)
  2120. +             || INSN_USES_REGNO (insn, i))
  2121. +               CLEAR_HARD_REG_BIT (*free, i);
  2122. +         }
  2123. +         } /* if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') */
  2124. +       insn = NEXT_INSN (insn);
  2125. +     }
  2126. +   if (insn != last)
  2127. +     fprintf (stderr, "%s (): didn't encounterd last!\n", funcname);
  2128. +   
  2129. + }
  2130. + /* removes a previous store of MEM if found, and returns INSN_UID of the insn
  2131. +    deleted. Otherwise returns 0. */
  2132. + static int
  2133. + remove_redundant_store (rtx mem, int block)
  2134. + {
  2135. +   rtx t_insn;
  2136. +   int regno;
  2137. +   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  2138. +     if ((t_insn = regno_holds_mem[regno].insn_store)
  2139. +     && GET_CODE (t_insn) == INSN
  2140. +         && rtx_equal_p (SET_DEST (PATTERN (t_insn)), mem))
  2141. +       {
  2142. +         if (basic_block_head[block] == t_insn)
  2143. +           basic_block_head[block] = NEXT_INSN (t_insn);
  2144. +         PUT_CODE (t_insn, NOTE);
  2145. +         NOTE_LINE_NUMBER (t_insn) = NOTE_INSN_DELETED;
  2146. +         NOTE_SOURCE_FILE (t_insn) = 0;
  2147. +         /* if the insn we have just deleted, was preceded with one or two risc
  2148. +            additions (i.e. memory_simplify added insns before it), and they are
  2149. +            not used for anything else, remove them as well */
  2150. +         if (RTX_IS_RISC_P (PREV_INSN (t_insn)))
  2151. +           {
  2152. +             PUT_CODE (PREV_INSN (t_insn), NOTE);
  2153. +             NOTE_LINE_NUMBER (PREV_INSN (t_insn)) = NOTE_INSN_DELETED;
  2154. +             NOTE_SOURCE_FILE (PREV_INSN (t_insn)) = 0;
  2155. +             if (RTX_IS_RISC_P (PREV_INSN (PREV_INSN (t_insn))))
  2156. +               {
  2157. +                 PUT_CODE (PREV_INSN (PREV_INSN (t_insn)), NOTE);
  2158. +                 NOTE_LINE_NUMBER (PREV_INSN (PREV_INSN (t_insn)))
  2159. +                                         = NOTE_INSN_DELETED;
  2160. +                 NOTE_SOURCE_FILE (PREV_INSN (PREV_INSN (t_insn))) = 0;
  2161. +               }
  2162. +           }
  2163. +            
  2164. +         return INSN_UID (t_insn);
  2165. +       }
  2166. +   return 0;
  2167. + }  /* remove_redundant_store (rtx mem) */
  2168. + /* intel2 - end */
  2169. + /* intel1 */
  2170. + /*
  2171. +   Try to eliminate unnecessary reg to reg moves, and also
  2172. +   if the destination is a register try to use that register
  2173. +   as one of the sources.  
  2174. +   EXAMPLE:
  2175. + (insn 618 614 616 (set (reg:SI %eax)
  2176. +         (mem/s:SI (plus:SI (mult:SI (reg/v:SI %ebx)
  2177. +                     (const_int 4))
  2178. +                 (reg:SI %esi)))) -1 (nil)
  2179. +     (nil))
  2180. + (insn 616 618 59 (set (reg:SI %esi)
  2181. +         (mem:SI (plus:SI (reg:SI %esp)
  2182. +                 (const_int 36)))) -1 (nil)
  2183. +     (nil))
  2184. + (insn:HI 59 616 60 (set (reg:SI %eax)
  2185. +         (ior:SI (reg:SI %eax)
  2186. +             (mem/s:SI (plus:SI (mult:SI (reg/v:SI %ebx)
  2187. +                         (const_int 4))
  2188. +                     (reg:SI %esi))))) 105 {iorsi3} (nil)
  2189. +     (nil))
  2190. + (insn 60 59 620 (set (reg:SI %eax)
  2191. +         (not:SI (reg:SI %eax))) 130 {one_cmplsi2} (insn_list 59 (nil))
  2192. +         (nil))
  2193. + (insn 620 60 61 (set (reg/v:SI %ecx)
  2194. +         (reg:SI %eax)) -1 (nil)
  2195. +     (expr_list:REG_DEAD (reg:SI %eax)
  2196. +     (nil)))
  2197. + WILL BECOME:
  2198. + (insn 618 614 616 (set (reg:SI %ecx)
  2199. +         (mem/s:SI (plus:SI (mult:SI (reg/v:SI %ebx)
  2200. +                     (const_int 4))
  2201. +                 (reg:SI %esi)))) -1 (nil)
  2202. +     (nil))
  2203. + (insn 616 618 59 (set (reg:SI %esi)
  2204. +         (mem:SI (plus:SI (reg:SI %esp)
  2205. +                 (const_int 36)))) -1 (nil)
  2206. +     (nil))
  2207. + (insn:HI 59 616 60 (set (reg:SI %ecx)
  2208. +         (ior:SI (reg:SI %ecx)
  2209. +             (mem/s:SI (plus:SI (mult:SI (reg/v:SI %ebx)
  2210. +                         (const_int 4))
  2211. +                     (reg:SI %esi))))) 105 {iorsi3} (nil)
  2212. +     (nil))
  2213. + (insn 60 59 620 (set (reg:SI %ecx)
  2214. +         (not:SI (reg:SI %ecx))) 130 {one_cmplsi2} (insn_list 59 (nil))
  2215. +         (nil))
  2216. + (note 620 60 61 "" NOTE_INSN_DELETED)
  2217. + The trigger for the optimization is:
  2218. + (insn 620 60 61 (set (reg/v:SI %ecx)
  2219. +         (reg:SI %eax)) -1 (nil)
  2220. +     (expr_list:REG_DEAD (reg:SI %eax)
  2221. +     (nil)))
  2222. + */
  2223. + void
  2224. + reg_to_reg_copy_opt (f, file)
  2225. +      rtx f;
  2226. +      FILE *file;
  2227. + {
  2228. +   rtx this_insn, regx, note, src;
  2229. +   int regno, success, length, i;
  2230. +   char * fmt;
  2231. +   if (file)
  2232. +     {
  2233. +       fprintf (file, "\n\ndoing reg to reg copy opt\n");
  2234. +     }
  2235. +   hard_reg_flow_analysis (f, NULL, 1);
  2236. +   this_insn = f;
  2237. +   while (this_insn)
  2238. +     {
  2239. +       if (GET_CODE (this_insn) == INSN 
  2240. +           && GET_CODE (PATTERN (this_insn)) == SET
  2241. +           && GET_CODE (SET_DEST (PATTERN (this_insn))) == REG
  2242. +           && GET_CODE (SET_SRC (PATTERN (this_insn))) == REG
  2243. +           && REGNO (SET_SRC (PATTERN (this_insn))) 
  2244. +              != REGNO (SET_DEST (PATTERN (this_insn))) 
  2245. +           && GET_MODE (SET_SRC (PATTERN (this_insn))) 
  2246. +              == GET_MODE (SET_DEST (PATTERN (this_insn))) 
  2247. +           && find_regno_note (this_insn, REG_DEAD, 
  2248. +                               REGNO (SET_SRC (PATTERN (this_insn))))
  2249. +          )
  2250. +         {
  2251. +           success = try_backwards_replace (SET_DEST (PATTERN (this_insn)), 
  2252. +                                  SET_SRC (PATTERN (this_insn)),
  2253. +                                  this_insn, 1, file);
  2254. +           if (!success)
  2255. +             {
  2256. +                success = try_forwards_replace (SET_DEST (PATTERN (this_insn)), 
  2257. +                                  SET_SRC (PATTERN (this_insn)),
  2258. +                                  this_insn, file);
  2259. +             }
  2260. +         }
  2261. +       else if (GET_CODE (this_insn) == INSN 
  2262. +                && GET_CODE (PATTERN (this_insn)) == SET
  2263. +                && GET_CODE (SET_DEST (PATTERN (this_insn))) == REG
  2264. +                && GET_CODE (SET_SRC (PATTERN (this_insn))) == SUBREG
  2265. +                && REGNO (SET_DEST (PATTERN (this_insn))) 
  2266. +                   != REGNO (SUBREG_REG (SET_SRC (PATTERN (this_insn))))
  2267. +                && SUBREG_WORD (SET_SRC (PATTERN (this_insn))) == 0
  2268. +                && GET_MODE (SET_SRC (PATTERN (this_insn))) 
  2269. +                   == GET_MODE (SET_DEST (PATTERN (this_insn))) 
  2270. +                && (note = find_regno_note (this_insn, REG_DEAD, 
  2271. +                                    REGNO (SUBREG_REG (SET_SRC (PATTERN (this_insn))))))
  2272. +                && rtx_equal_p (XEXP (note, 0), 
  2273. +                                SUBREG_REG (SET_SRC (PATTERN (this_insn))))
  2274. +                && HARD_REGNO_NREGS (REGNO (SET_DEST (PATTERN (this_insn))),
  2275. +                                 GET_MODE (SUBREG_REG (SET_SRC (PATTERN (this_insn)))))
  2276. +                    ==
  2277. +                   HARD_REGNO_NREGS (REGNO (SET_DEST (PATTERN (this_insn))),
  2278. +                             GET_MODE (SET_DEST (PATTERN (this_insn))))
  2279. +                && HARD_REGNO_NREGS (REGNO (SET_DEST (PATTERN (this_insn))),
  2280. +                             GET_MODE (SET_DEST (PATTERN (this_insn))))
  2281. +                    == 1
  2282. +                && HARD_REGNO_MODE_OK (REGNO (SET_DEST (PATTERN (this_insn))) ,
  2283. +                                       GET_MODE (SUBREG_REG (SET_SRC (PATTERN (this_insn)))))
  2284. +               )
  2285. +         {
  2286. +           regx = gen_rtx (REG, 
  2287. +                           GET_MODE (SUBREG_REG (SET_SRC (PATTERN (this_insn)))),
  2288. +                           REGNO (SET_DEST (PATTERN (this_insn))));
  2289. +           success 
  2290. +            = try_backwards_replace (regx,
  2291. +                                  SUBREG_REG (SET_SRC (PATTERN (this_insn))),
  2292. +                                  this_insn, 1, file);
  2293. +           if (!success)
  2294. +             {
  2295. +               success 
  2296. +                = try_forwards_replace (SET_DEST (PATTERN (this_insn)),
  2297. +                                  SET_SRC (PATTERN (this_insn)),
  2298. +                                  this_insn, file);
  2299. +             }
  2300. +         }
  2301. +       else if (GET_CODE (this_insn) == INSN 
  2302. +           && GET_CODE (PATTERN (this_insn)) == SET
  2303. +           && GET_CODE (SET_DEST (PATTERN (this_insn))) == REG
  2304. +           && GET_CODE (SET_SRC (PATTERN (this_insn))) != MEM
  2305. +           && GET_CODE (SET_SRC (PATTERN (this_insn))) != SUBREG
  2306. +           && !reg_overlap_mentioned_p (SET_DEST (PATTERN (this_insn)),
  2307. +                                        SET_SRC (PATTERN (this_insn)))
  2308. +           )
  2309. +         {
  2310. +           src = SET_SRC (PATTERN (this_insn));
  2311. +           fmt = GET_RTX_FORMAT (GET_CODE (src));
  2312. +           length = GET_RTX_LENGTH (GET_CODE (src));
  2313. +           for (i=0; i<length; i++)
  2314. +             {
  2315. +               if (fmt[i] == 'e' 
  2316. +                   && GET_CODE (XEXP (src, i)) == SUBREG)
  2317. +                 {  /* Makes matters too complex.  */
  2318. +                   return;
  2319. +                 }
  2320. +             }
  2321. +           for (i=0; i<length; i++)
  2322. +             {
  2323. +               if (fmt[i] == 'e' 
  2324. +                   && GET_CODE (XEXP (src, i)) == REG
  2325. +                   && (note = find_regno_note (this_insn, REG_DEAD,
  2326. +                                               REGNO (XEXP (src, i))))
  2327. +                   && rtx_equal_p (XEXP (src, i), XEXP (note, 0))
  2328. +                   )
  2329. +                 { /* One of the sources dies in this insn -
  2330. +                      see if the destination register can be used
  2331. +                      to replace that register.  This has a chance
  2332. +                      of producing better code e.g. reg1 <- reg1 AND reg3
  2333. +                      produces more efficient code than 
  2334. +                      reg1 <- reg2 AND reg3.  */
  2335. +                   rtx regx, regy;
  2336. +                   regy = XEXP (src, i);
  2337. +                   regx = SET_DEST (PATTERN (this_insn));
  2338. +                   if (reg_overlap_mentioned_p (regx, PATTERN (this_insn)))
  2339. +                     {
  2340. +                       break;
  2341. +                     }
  2342. +                   if (GET_MODE (regx) != GET_MODE (regy))
  2343. +                     {
  2344. +                       if (HARD_REGNO_NREGS (REGNO (regx), GET_MODE (regy)) != 1
  2345. +                           || 
  2346. +                           !(HARD_REGNO_MODE_OK (REGNO (regx), GET_MODE (regy))))
  2347. +                         {
  2348. +                           continue;
  2349. +                         }
  2350. +                       regx = gen_rtx (REG, GET_MODE (regy), REGNO (regx)); 
  2351. +                     }
  2352. +                   if (try_backwards_replace (regx, regy, this_insn, 0, file))
  2353. +                     {
  2354. +                       remove_note (this_insn, note);
  2355. +                       break; /* Since now the dest reg is 
  2356. +                                 mentioned in the src.  */
  2357. +                     }
  2358. +                 }
  2359. +             }
  2360. +         }
  2361. +       this_insn = NEXT_INSN (this_insn);
  2362. +     }
  2363. +   if (file)
  2364. +     {
  2365. +       fprintf (file, "\n");
  2366. +     }
  2367. + }
  2368. + /*
  2369. +   insn is of the form
  2370. +      regx <- regy (regy dead)
  2371. +    or
  2372. +      regx <- SUBREG (regy) (regy dead)
  2373. +    or
  2374. +      regx <- OP (regy, ...) (regy dead)
  2375. +    
  2376. +   Search backwards for last previous setting of regy in which the 
  2377. +   setting of regy can be replaced with regx.  If it can then
  2378. +   do the replacement and then if delete_flag is set delete insn.  
  2379. + */
  2380. + static
  2381. + int
  2382. + try_backwards_replace (regx, regy, insn, delete_flag, file)
  2383. +   rtx regx, regy, insn;
  2384. +   FILE *file;
  2385. + {
  2386. +   rtx this_insn, set_insn, stop_insn;
  2387. +   int stop_replacement = 0;
  2388. +   int found = 0, insn_code_number, not_yet_recoged;
  2389. +   
  2390. +   
  2391. +   if (file)
  2392. +     {
  2393. +       fprintf (file, "\ninsn %d reg%d <- reg%d (reg%d dead) (try backwards)\n", 
  2394. +       INSN_UID(insn), REGNO (regx), REGNO (regy), REGNO(regy));
  2395. +     }
  2396. +   this_insn = prev_nonnote_insn (insn);
  2397. +   /* Find the first previous insn in the block that sets regy and in
  2398. +      which regy can be replaced with regx */
  2399. +   while (!found && this_insn 
  2400. +          && !(GET_CODE (this_insn) == CODE_LABEL 
  2401. +               || GET_CODE (this_insn) == CALL_INSN
  2402. +               || GET_CODE (this_insn) == JUMP_INSN))
  2403. +     {
  2404. +       if (GET_CODE (this_insn) == INSN)
  2405. +         {
  2406. +           if (GET_CODE (PATTERN (this_insn)) != SET)
  2407. +             {
  2408. +               return (0);
  2409. +             }
  2410. +           if (GET_CODE (SET_DEST (PATTERN (this_insn))) == REG)
  2411. +             {
  2412. +               if (REGNO (regx) == REGNO (SET_DEST (PATTERN (this_insn))))
  2413. +                 {
  2414. +                   return (0);
  2415. +                 }
  2416. +               else if (REGNO (regy) == REGNO (SET_DEST (PATTERN (this_insn))))
  2417. +                 {
  2418. +                   if (GET_MODE (regy) 
  2419. +                        == GET_MODE (SET_DEST (PATTERN (this_insn))))
  2420. +                     {
  2421. + #ifdef REGISTER_CONSTRAINTS
  2422. +                       if (INSN_CODE (this_insn) == -1)
  2423. +                         {
  2424. +                           INSN_CODE (this_insn) 
  2425. +                             = recog (PATTERN (this_insn), this_insn, 0);
  2426. +                         }
  2427. + #endif
  2428. +                       SET_DEST (PATTERN (this_insn)) = regx;
  2429. + #ifdef REGISTER_CONSTRAINTS
  2430. +                   if ((insn_code_number
  2431. +                        = recog (PATTERN (this_insn), this_insn, 0)) < 0
  2432. +                           || (INSN_CODE (this_insn) != -1
  2433. +                               && insn_code_number != INSN_CODE (this_insn)))
  2434. +                     {/* Need to have the same code number since 
  2435. +                         constraints are sometimes more lax than 
  2436. +                         predicates */
  2437. +                   SET_DEST (PATTERN (this_insn)) = regy;
  2438. +                   stop_replacement = 1;
  2439. +                 }
  2440. +                 else
  2441. +                     {
  2442. +                       INSN_CODE (this_insn) = insn_code_number;
  2443. +                   insn_extract (this_insn);
  2444. +                   if(!constrain_operands (INSN_CODE (this_insn), 1))
  2445. +                         {
  2446. +                       /* restore the previous situation */
  2447. +                         SET_DEST (PATTERN (this_insn)) = regy;
  2448. +                           /*INSN_CODE (this_insn) 
  2449. +                            = recog (PATTERN (this_insn), this_insn, 0);*/
  2450. +                       stop_replacement = 1;
  2451. +                      }
  2452. +                 }
  2453. +         
  2454. + #endif
  2455. +                       if (!stop_replacement)
  2456. +                         {
  2457. +                           found = 1;
  2458. +                           set_insn = this_insn;
  2459. +                         }
  2460. +                     }
  2461. +                   else
  2462. +                     {
  2463. +                       return (0);
  2464. +                     }
  2465. +                 }
  2466. +             }
  2467. +           else if (reg_overlap_mentioned_p (regx, SET_DEST (PATTERN (this_insn))))
  2468. +             {
  2469. +               return (0);
  2470. +             }
  2471. +           if (!found
  2472. +               && reg_overlap_mentioned_p (regx, SET_SRC (PATTERN (this_insn))))
  2473. +             {
  2474. +               return (0);
  2475. +             }
  2476. +         }
  2477. +       if (!found)
  2478. +         {
  2479. +           stop_replacement = 0;
  2480. +           this_insn = prev_nonnote_insn (this_insn);
  2481. +         }
  2482. +     }
  2483. +   if (found)
  2484. +     {/* We have found the insn that last sets regy and successfully 
  2485. +         replaced regx as the dest of that insn.  
  2486. +         In all insns between set_insn and insn replace regy with regx.  */
  2487. +       stop_replacement = 0;
  2488. +       this_insn = next_nonnote_insn (set_insn);
  2489. +       init_undo_buf ();
  2490. +       stop_insn = next_nonnote_insn (insn);
  2491. +       while (this_insn != stop_insn && !stop_replacement)
  2492. +         {
  2493. + #ifdef REGISTER_CONSTRAINTS
  2494. +           if (INSN_CODE (this_insn) == -1)
  2495. +             {
  2496. +               INSN_CODE (this_insn) 
  2497. +                 = recog (PATTERN (this_insn), this_insn, 0);
  2498. +             }
  2499. + #endif
  2500. +           subst_in_insn (this_insn, PATTERN (this_insn), regy, regx, 0, 0);
  2501. +           if (reg_set_p (regy, this_insn)
  2502. +               || reg_overlap_mentioned_p (regy, PATTERN (this_insn)))
  2503. +             { /* regy was used in some other mode - fail */
  2504. +               stop_replacement = 1;
  2505. +             }
  2506. + #ifdef REGISTER_CONSTRAINTS
  2507. +           if (stop_replacement
  2508. +               ||
  2509. +               (insn_code_number
  2510. +                 = recog (PATTERN (this_insn), this_insn, 0)) < 0
  2511. +               || (INSN_CODE (this_insn) != -1
  2512. +                   && insn_code_number != INSN_CODE (this_insn)))
  2513. +             {/* Need to have the same code number since constraints
  2514. +                  are sometimes more lax than predicates */
  2515. +               stop_replacement = 1;
  2516. +             }
  2517. +           else
  2518. +             {
  2519. +               INSN_CODE (this_insn) = insn_code_number;
  2520. +               insn_extract (this_insn);
  2521. +           if(!constrain_operands (INSN_CODE (this_insn), 1))
  2522. +             {
  2523. +               stop_replacement = 1;
  2524. +             }
  2525. +             }
  2526. + #endif
  2527. +           this_insn = next_nonnote_insn ( this_insn);
  2528. +         }
  2529. +         
  2530. +       if (stop_replacement)
  2531. +         { /* A replacement was unsuccessful - undo all of the replacements */
  2532. +           SET_DEST (PATTERN (set_insn)) = regy;
  2533. +           /*INSN_CODE (this_insn) 
  2534. +             = recog (PATTERN (this_insn), this_insn, 0);*/
  2535. +           this_insn = next_nonnote_insn (set_insn);
  2536. +           loop_undo_all ();
  2537. +           /*while (this_insn != insn)
  2538. +             {
  2539. +               INSN_CODE (this_insn) 
  2540. +                 = recog (PATTERN (this_insn), this_insn, 0); 
  2541. +               this_insn = next_nonnote_insn (this_insn);
  2542. +             }*/
  2543. +           return (0);
  2544. +         }
  2545. +       else 
  2546. +         { 
  2547. +       if (file)
  2548. +         {
  2549. +           fprintf (file, "replaced dest reg%d of insn %d with reg%d\n",
  2550. +             REGNO (regy), INSN_UID (set_insn), REGNO (regx));
  2551. +           fprintf (file, " in insns %d through %d replaced reg%d with reg%d\n",
  2552. +             INSN_UID (next_nonnote_insn (set_insn)),
  2553. +             INSN_UID (insn), 
  2554. +             REGNO (regy), REGNO (regx));
  2555. +         }
  2556. +           if (delete_flag)
  2557. +             {/* Delete insn */
  2558. +               PUT_CODE (insn, NOTE);
  2559. +           NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
  2560. +           NOTE_SOURCE_FILE (insn) = 0;
  2561. +           if (file)
  2562. +             {
  2563. +               fprintf (file, " deleted insn %d\n", INSN_UID (insn));
  2564. +             }
  2565. +         }
  2566. +           return (1);
  2567. +         }
  2568. +     }
  2569. +   return (0);
  2570. + }
  2571. + /*
  2572. +   insn is of the form
  2573. +      regx <- regy (regy dead)
  2574. +    or
  2575. +      regx <- SUBREG (regy) (regy dead)
  2576. +    
  2577. +   Search forwards for next insn in which the regx is dead.
  2578. +   Try to replace all uses of regx with regy in those insns
  2579. +   and if successful then delete insn.  
  2580. + */
  2581. + static
  2582. + int
  2583. + try_forwards_replace (regx, regy, insn, file)
  2584. +   rtx regx, regy, insn;
  2585. +   FILE *file;
  2586. + {
  2587. +   rtx this_insn, dead_insn, dead_note, stop_insn;
  2588. +   int stop_replacement = 0;
  2589. +   int found = 0, insn_code_number;
  2590. +   
  2591. +   
  2592. +   if (file)
  2593. +     {
  2594. +       if (GET_CODE (regy) == REG )
  2595. +         fprintf (file, "\ninsn %d reg%d <- reg%d (reg%d dead) (try forwards)\n", 
  2596. +         INSN_UID(insn), REGNO (regx), REGNO (regy), REGNO(regy));
  2597. +       else
  2598. +         fprintf (file, "\ninsn %d reg%d <- reg%d (reg%d dead) (try forwards)\n", 
  2599. +         INSN_UID(insn), REGNO (regx), 
  2600. +         REGNO (SUBREG_REG (regy)), 
  2601. +         REGNO (SUBREG_REG (regy)));
  2602. +     }
  2603. +   this_insn = next_nonnote_insn (insn);
  2604. +   /* Find the next insn in the block where regx dies */
  2605. +   while (!found && this_insn 
  2606. +          && !(GET_CODE (this_insn) == CODE_LABEL 
  2607. +               || GET_CODE (this_insn) == CALL_INSN
  2608. +               || GET_CODE (this_insn) == JUMP_INSN))
  2609. +     {
  2610. +       if (GET_CODE (this_insn) == INSN)
  2611. +         {
  2612. +           if (GET_CODE (PATTERN (insn)) == USE
  2613. +               && reg_overlap_mentioned_p (regx, SET_DEST (PATTERN (insn))))
  2614. +             {
  2615. +               return (0);
  2616. +             }
  2617. +           if (reg_set_p (regy, this_insn))
  2618. +             {
  2619. +               return (0);
  2620. +             }
  2621. +           else if ((dead_note 
  2622. +                     = find_regno_note (this_insn, REG_DEAD, REGNO (regx)))
  2623. +                    && rtx_equal_p (XEXP (dead_note, 0), regx))
  2624. +             {
  2625. +               found = 1;
  2626. +               dead_insn = this_insn;
  2627. +             }
  2628. +         }
  2629. +       if (!found)
  2630. +         {
  2631. +           this_insn = next_nonnote_insn (this_insn);
  2632. +         }
  2633. +     }
  2634. +   if (found)
  2635. +     {/* We have found the insn where regx dies.  */
  2636. +       stop_replacement = 0;
  2637. +       this_insn = next_nonnote_insn (insn);
  2638. +       init_undo_buf ();
  2639. +       stop_insn = next_nonnote_insn (dead_insn);
  2640. +       while (this_insn != stop_insn && !stop_replacement)
  2641. +         {
  2642. + #ifdef REGISTER_CONSTRAINTS
  2643. +           if (INSN_CODE (this_insn) == -1)
  2644. +             {
  2645. +               INSN_CODE (this_insn) 
  2646. +                 = recog (PATTERN (this_insn), this_insn, 0);
  2647. +             }
  2648. + #endif
  2649. +           subst_in_insn (this_insn, PATTERN (this_insn), regx, regy, 0, 0);
  2650. +           if (reg_set_p (regx, this_insn)
  2651. +               || reg_overlap_mentioned_p (regx, PATTERN (this_insn)))
  2652. +             { /* regx is used in some other mode - fail.  */
  2653. +               if (file)
  2654. +                 {
  2655. +                   fprintf (file, "fail insn %d reg %d still mentioned\n",
  2656. +                   INSN_UID (this_insn), REGNO (regx));
  2657. +                   tdebug_rtx (this_insn, file);
  2658. +                 }
  2659. +               stop_replacement = 1;
  2660. +             }
  2661. + #ifdef REGISTER_CONSTRAINTS
  2662. +           if (stop_replacement
  2663. +               ||
  2664. +               (insn_code_number
  2665. +                 = recog (PATTERN (this_insn), this_insn, 0)) < 0
  2666. +               || (INSN_CODE (this_insn) != -1
  2667. +                   && insn_code_number != INSN_CODE (this_insn)))
  2668. +             { /* Need to have the same code number since constraints
  2669. +                  are sometimes more lax than predicates */
  2670. +               if (file)
  2671. +                 {
  2672. +                   fprintf (file, "fail insn %d new_recog %d old_recog %d\n",
  2673. +                   INSN_UID (this_insn), insn_code_number, INSN_CODE (this_insn));
  2674. +                 }
  2675. +               stop_replacement = 1;
  2676. +             }
  2677. +           else
  2678. +             {
  2679. +               INSN_CODE (this_insn) = insn_code_number;
  2680. +               insn_extract (this_insn);
  2681. +           if(!constrain_operands (INSN_CODE (this_insn), 1))
  2682. +             {
  2683. +               stop_replacement = 1;
  2684. +             }
  2685. +             }
  2686. + #endif
  2687. +           this_insn = next_nonnote_insn ( this_insn);
  2688. +         }
  2689. +         
  2690. +       if (stop_replacement)
  2691. +         { /* A replacement was unsuccessful - undo all of the replacements */
  2692. +           this_insn = next_nonnote_insn (insn);
  2693. +           loop_undo_all ();
  2694. +           stop_insn = next_nonnote_insn (dead_insn);
  2695. +           /*while (this_insn != stop_insn)
  2696. +             {
  2697. +               INSN_CODE (this_insn) 
  2698. +                  = recog (PATTERN (this_insn), this_insn, 0); 
  2699. +               this_insn = next_nonnote_insn (this_insn);
  2700. +             }*/
  2701. +           return (0);
  2702. +         }
  2703. +       else
  2704. +         { /* Delete insn */
  2705. +           PUT_CODE (insn, NOTE);
  2706. +       NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
  2707. +       NOTE_SOURCE_FILE (insn) = 0;
  2708. +       XEXP (dead_note, 0) = regy;
  2709. +       if (file)
  2710. +         {
  2711. +           fprintf (file, " in insns %d through %d replaced reg%d with reg%d\n",
  2712. +                INSN_UID (next_nonnote_insn (insn)),
  2713. +                INSN_UID (dead_insn), 
  2714. +                REGNO (regx), 
  2715. +                GET_CODE (regy) == REG 
  2716. +                  ? REGNO (regy)
  2717. +                  : REGNO (SUBREG_REG (regy)));
  2718. +           fprintf (file, " deleted insn %d\n", INSN_UID (insn));
  2719. +         }
  2720. +           return (1);
  2721. +         }
  2722. +     }
  2723. +   return (0);
  2724.   }
  2725. diff -rNci gcc-2.7.2/config/i386/i386.c gcc-2.7.2p/config/i386/i386.c
  2726. *** gcc-2.7.2/config/i386/i386.c    Sun Oct 22 11:13:21 1995
  2727. --- gcc-2.7.2p/config/i386/i386.c    Tue Jan 23 09:34:59 1996
  2728. ***************
  2729. *** 1,6 ****
  2730. --- 1,9 ----
  2731.   /* Subroutines for insn-output.c for Intel X86.
  2732.      Copyright (C) 1988, 1992, 1994, 1995 Free Software Foundation, Inc.
  2733.   
  2734. +    Pentium cpu support and other enhancements by Tevi Devor Intel Corp.
  2735. +    (tevi@iil.intel.com).
  2736. +   
  2737.   This file is part of GNU CC.
  2738.   
  2739.   GNU CC is free software; you can redistribute it and/or modify
  2740. ***************
  2741. *** 35,40 ****
  2742. --- 38,45 ----
  2743.   #include "flags.h"
  2744.   #include "function.h"
  2745.   
  2746. + /* intel1 Need the EXTRA_CONSTRAINT - changed s to */
  2747. + #if 0
  2748.   #ifdef EXTRA_CONSTRAINT
  2749.   /* If EXTRA_CONSTRAINT is defined, then the 'S'
  2750.      constraint in REG_CLASS_FROM_LETTER will no longer work, and various
  2751. ***************
  2752. *** 43,48 ****
  2753. --- 48,57 ----
  2754.   /* The previous line used to be #error, but some compilers barf
  2755.      even if the conditional was untrue.  */
  2756.   #endif
  2757. + #endif
  2758. + /* which cpu are we scheduling for intel1*/
  2759. + enum processor_type x86_cpu;
  2760.   
  2761.   #define AT_BP(mode) (gen_rtx (MEM, (mode), frame_pointer_rtx))
  2762.   
  2763. ***************
  2764. *** 53,88 ****
  2765.   char *output_move_const_single ();
  2766.   char *output_fp_cc0_set ();
  2767.   
  2768.   char *hi_reg_name[] = HI_REGISTER_NAMES;
  2769.   char *qi_reg_name[] = QI_REGISTER_NAMES;
  2770.   char *qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
  2771.   
  2772. - /* Array of the smallest class containing reg number REGNO, indexed by
  2773. -    REGNO.  Used by REGNO_REG_CLASS in i386.h. */
  2774. - enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
  2775. - {
  2776. -   /* ax, dx, cx, bx */
  2777. -   AREG, DREG, CREG, BREG,
  2778. -   /* si, di, bp, sp */
  2779. -   SIREG, DIREG, INDEX_REGS, GENERAL_REGS,
  2780. -   /* FP registers */
  2781. -   FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
  2782. -   FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,       
  2783. -   /* arg pointer */
  2784. -   INDEX_REGS
  2785. - };
  2786. - /* Test and compare insns in i386.md store the information needed to
  2787. -    generate branch and scc insns here.  */
  2788. - struct rtx_def *i386_compare_op0 = NULL_RTX;
  2789. - struct rtx_def *i386_compare_op1 = NULL_RTX;
  2790. - struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
  2791.   /* Register allocation order */
  2792.   char *i386_reg_alloc_order;
  2793. ! static char regs_allocated[FIRST_PSEUDO_REGISTER];
  2794.   
  2795.   /* # of registers to use to pass arguments. */
  2796.   char *i386_regparm_string;            /* # registers to use to pass args */
  2797. --- 62,77 ----
  2798.   char *output_move_const_single ();
  2799.   char *output_fp_cc0_set ();
  2800.   
  2801. + /* intel1 */
  2802. + static int opt_level=0;
  2803.   char *hi_reg_name[] = HI_REGISTER_NAMES;
  2804.   char *qi_reg_name[] = QI_REGISTER_NAMES;
  2805.   char *qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
  2806.   
  2807.   /* Register allocation order */
  2808.   char *i386_reg_alloc_order;
  2809. ! /*static char regs_allocated[FIRST_PSEUDO_REGISTER];*/
  2810.   
  2811.   /* # of registers to use to pass arguments. */
  2812.   char *i386_regparm_string;            /* # registers to use to pass args */
  2813. ***************
  2814. *** 97,284 ****
  2815.   int i386_align_jumps;                /* power of two alignment for non-loop jumps */
  2816.   int i386_align_funcs;                /* power of two alignment for functions */
  2817.   
  2818. ! /* Sometimes certain combinations of command options do not make
  2819. !    sense on a particular target machine.  You can define a macro
  2820. !    `OVERRIDE_OPTIONS' to take account of this.  This macro, if
  2821. !    defined, is executed once just after all the command options have
  2822. !    been parsed.
  2823. !    Don't use this macro to turn on various extra optimizations for
  2824. !    `-O'.  That is what `OPTIMIZATION_OPTIONS' is for.  */
  2825. ! void
  2826. ! override_options ()
  2827. ! {
  2828. !   int ch, i, regno;
  2829. !   char *p;
  2830. !   int def_align;
  2831. ! #ifdef SUBTARGET_OVERRIDE_OPTIONS
  2832. !   SUBTARGET_OVERRIDE_OPTIONS;
  2833. ! #endif
  2834. !   /* Validate registers in register allocation order */
  2835. !   if (i386_reg_alloc_order)
  2836. !     {
  2837. !       for (i = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++)
  2838. !     {
  2839. !       switch (ch)
  2840. !         {
  2841. !         case 'a':    regno = 0;    break;
  2842. !         case 'd':    regno = 1;    break;
  2843. !         case 'c':    regno = 2;    break;
  2844. !         case 'b':    regno = 3;    break;
  2845. !         case 'S':    regno = 4;    break;
  2846. !         case 'D':    regno = 5;    break;
  2847. !         case 'B':    regno = 6;    break;
  2848. !         default:    fatal ("Register '%c' is unknown", ch);
  2849. !         }
  2850. !       if (regs_allocated[regno])
  2851. !         fatal ("Register '%c' was already specified in the allocation order", ch);
  2852. !       regs_allocated[regno] = 1;
  2853. !     }
  2854. !     }
  2855. !   /* Validate -mregparm= value */
  2856. !   if (i386_regparm_string)
  2857. !     {
  2858. !       i386_regparm = atoi (i386_regparm_string);
  2859. !       if (i386_regparm < 0 || i386_regparm > REGPARM_MAX)
  2860. !     fatal ("-mregparm=%d is not between 0 and %d", i386_regparm, REGPARM_MAX);
  2861. !     }
  2862. !   def_align = (TARGET_386) ? 2 : 4;
  2863. !   /* Validate -malign-loops= value, or provide default */
  2864. !   if (i386_align_loops_string)
  2865. !     {
  2866. !       i386_align_loops = atoi (i386_align_loops_string);
  2867. !       if (i386_align_loops < 0 || i386_align_loops > MAX_CODE_ALIGN)
  2868. !     fatal ("-malign-loops=%d is not between 0 and %d",
  2869. !            i386_align_loops, MAX_CODE_ALIGN);
  2870. !     }
  2871. !   else
  2872. !     i386_align_loops = 2;
  2873. !   /* Validate -malign-jumps= value, or provide default */
  2874. !   if (i386_align_jumps_string)
  2875. !     {
  2876. !       i386_align_jumps = atoi (i386_align_jumps_string);
  2877. !       if (i386_align_jumps < 0 || i386_align_jumps > MAX_CODE_ALIGN)
  2878. !     fatal ("-malign-jumps=%d is not between 0 and %d",
  2879. !            i386_align_jumps, MAX_CODE_ALIGN);
  2880. !     }
  2881. !   else
  2882. !     i386_align_jumps = def_align;
  2883. !   /* Validate -malign-functions= value, or provide default */
  2884. !   if (i386_align_funcs_string)
  2885. !     {
  2886. !       i386_align_funcs = atoi (i386_align_funcs_string);
  2887. !       if (i386_align_funcs < 0 || i386_align_funcs > MAX_CODE_ALIGN)
  2888. !     fatal ("-malign-functions=%d is not between 0 and %d",
  2889. !            i386_align_funcs, MAX_CODE_ALIGN);
  2890. !     }
  2891. !   else
  2892. !     i386_align_funcs = def_align;
  2893. ! }
  2894. ! /* A C statement (sans semicolon) to choose the order in which to
  2895. !    allocate hard registers for pseudo-registers local to a basic
  2896. !    block.
  2897. !    Store the desired register order in the array `reg_alloc_order'.
  2898. !    Element 0 should be the register to allocate first; element 1, the
  2899. !    next register; and so on.
  2900. !    The macro body should not assume anything about the contents of
  2901. !    `reg_alloc_order' before execution of the macro.
  2902. !    On most machines, it is not necessary to define this macro.  */
  2903.   
  2904. ! void
  2905. ! order_regs_for_local_alloc ()
  2906.   {
  2907. !   int i, ch, order, regno;
  2908. !   /* User specified the register allocation order */
  2909. !   if (i386_reg_alloc_order)
  2910. !     {
  2911. !       for (i = order = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++)
  2912. !     {
  2913. !       switch (ch)
  2914. !         {
  2915. !         case 'a':    regno = 0;    break;
  2916. !         case 'd':    regno = 1;    break;
  2917. !         case 'c':    regno = 2;    break;
  2918. !         case 'b':    regno = 3;    break;
  2919. !         case 'S':    regno = 4;    break;
  2920. !         case 'D':    regno = 5;    break;
  2921. !         case 'B':    regno = 6;    break;
  2922. !         }
  2923. !       reg_alloc_order[order++] = regno;
  2924. !     }
  2925. !       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  2926. !     {
  2927. !       if (!regs_allocated[i])
  2928. !         reg_alloc_order[order++] = i;
  2929. !     }
  2930. !     }
  2931. !   /* If users did not specify a register allocation order, favor eax
  2932. !      normally except if DImode variables are used, in which case
  2933. !      favor edx before eax, which seems to cause less spill register
  2934. !      not found messages.  */
  2935. !   else
  2936. !     {
  2937. !       rtx insn;
  2938. !       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  2939. !     reg_alloc_order[i] = i;
  2940. !       if (optimize)
  2941. !     {
  2942. !       int use_dca = FALSE;
  2943. !       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
  2944. !         {
  2945. !           if (GET_CODE (insn) == INSN)
  2946. !         {
  2947. !           rtx set = NULL_RTX;
  2948. !           rtx pattern = PATTERN (insn);
  2949. !           if (GET_CODE (pattern) == SET)
  2950. !             set = pattern;
  2951. !           else if ((GET_CODE (pattern) == PARALLEL
  2952. !                 || GET_CODE (pattern) == SEQUENCE)
  2953. !                && GET_CODE (XVECEXP (pattern, 0, 0)) == SET)
  2954. !             set = XVECEXP (pattern, 0, 0);
  2955. !           if (set && GET_MODE (SET_SRC (set)) == DImode)
  2956. !             {
  2957. !               use_dca = TRUE;
  2958. !               break;
  2959. !             }
  2960. !         }
  2961. !         }
  2962.   
  2963. !       if (use_dca)
  2964. !         {
  2965. !           reg_alloc_order[0] = 1;    /* edx */
  2966. !           reg_alloc_order[1] = 2;    /* ecx */
  2967. !           reg_alloc_order[2] = 0;    /* eax */
  2968. !         }
  2969. !     }
  2970. !     }
  2971. ! }
  2972.   
  2973.   
  2974.   /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
  2975.      attribute for DECL.  The attributes in ATTRIBUTES have previously been
  2976. --- 86,112 ----
  2977.   int i386_align_jumps;                /* power of two alignment for non-loop jumps */
  2978.   int i386_align_funcs;                /* power of two alignment for functions */
  2979.   
  2980. ! /* Array of the smallest class containing reg number REGNO, indexed by
  2981. !    REGNO.  Used by REGNO_REG_CLASS in i386.h. */
  2982.   
  2983. ! enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
  2984.   {
  2985. !   /* ax, dx, cx, bx */
  2986. !   AREG, DREG, CREG, BREG,
  2987. !   /* si, di, bp, sp */
  2988. !   SIREG, DIREG, INDEX_REGS, GENERAL_REGS,
  2989. !   /* FP registers */
  2990. !   FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
  2991. !   FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,       
  2992. !   /* arg pointer */
  2993. !   INDEX_REGS
  2994. ! };
  2995.   
  2996. ! /* Test and compare insns in i386.md store the information needed to
  2997. !    generate branch and scc insns here.  */
  2998.   
  2999. + struct rtx_def *i386_compare_op0, *i386_compare_op1;
  3000. + struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
  3001.   
  3002.   /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
  3003.      attribute for DECL.  The attributes in ATTRIBUTES have previously been
  3004. ***************
  3005. *** 635,640 ****
  3006. --- 463,469 ----
  3007.        int dies;
  3008.   {
  3009.     rtx xops[4];
  3010. +   int def_align;
  3011.     int size = GET_MODE_SIZE (GET_MODE (dest));
  3012.   
  3013.     xops[0] = AT_SP (Pmode);
  3014. ***************
  3015. *** 681,686 ****
  3016. --- 510,558 ----
  3017.         output_asm_insn (AS1 (pop%L0,%0), &dest);
  3018.       }
  3019.       }
  3020. +   /* Validate -mregparm= value */
  3021. +   if (i386_regparm_string)
  3022. +     {
  3023. +       i386_regparm = atoi (i386_regparm_string);
  3024. +       if (i386_regparm < 0 || i386_regparm > REGPARM_MAX)
  3025. +     fatal ("-mregparm=%d is not between 0 and %d", i386_regparm, REGPARM_MAX);
  3026. +     }
  3027. +   def_align = (TARGET_386) ? 2 : 4;
  3028. +   /* Validate -malign-loops= value, or provide default */
  3029. +   if (i386_align_loops_string)
  3030. +     {
  3031. +       i386_align_loops = atoi (i386_align_loops_string);
  3032. +       if (i386_align_loops < 0 || i386_align_loops > MAX_CODE_ALIGN)
  3033. +     fatal ("-malign-loops=%d is not between 0 and %d",
  3034. +            i386_align_loops, MAX_CODE_ALIGN);
  3035. +     }
  3036. +   else
  3037. +     i386_align_loops = 2;
  3038. +   /* Validate -malign-jumps= value, or provide default */
  3039. +   if (i386_align_jumps_string)
  3040. +     {
  3041. +       i386_align_jumps = atoi (i386_align_jumps_string);
  3042. +       if (i386_align_jumps < 0 || i386_align_jumps > MAX_CODE_ALIGN)
  3043. +     fatal ("-malign-jumps=%d is not between 0 and %d",
  3044. +            i386_align_jumps, MAX_CODE_ALIGN);
  3045. +     }
  3046. +   else
  3047. +     i386_align_jumps = def_align;
  3048. +   /* Validate -malign-functions= value, or provide default */
  3049. +   if (i386_align_funcs_string)
  3050. +     {
  3051. +       i386_align_funcs = atoi (i386_align_funcs_string);
  3052. +       if (i386_align_funcs < 0 || i386_align_funcs > MAX_CODE_ALIGN)
  3053. +     fatal ("-malign-functions=%d is not between 0 and %d",
  3054. +            i386_align_funcs, MAX_CODE_ALIGN);
  3055. +     }
  3056. +   else
  3057. +     i386_align_funcs = def_align;
  3058.   }
  3059.   
  3060.   char *
  3061. ***************
  3062. *** 735,741 ****
  3063.     abort ();
  3064.   }
  3065.   
  3066.   /* Output an insn to add the constant N to the register X.  */
  3067.   
  3068.   static void
  3069. --- 607,612 ----
  3070. ***************
  3071. *** 744,768 ****
  3072.        rtx x;
  3073.   {
  3074.     rtx xops[2];
  3075. !   xops[0] = x;
  3076. !   if (n == -1)
  3077. !     output_asm_insn (AS1 (dec%L0,%0), xops);
  3078. !   else if (n == 1)
  3079. !     output_asm_insn (AS1 (inc%L0,%0), xops);
  3080. !   else if (n < 0)
  3081.       {
  3082. !       xops[1] = GEN_INT (-n);
  3083. !       output_asm_insn (AS2 (sub%L0,%1,%0), xops);
  3084.       }
  3085.     else if (n > 0)
  3086.       {
  3087. !       xops[1] = GEN_INT (n);
  3088. !       output_asm_insn (AS2 (add%L0,%1,%0), xops);
  3089.       }
  3090.   }
  3091.   
  3092.   /* Output assembler code to perform a doubleword move insn
  3093.      with operands OPERANDS.  */
  3094.   
  3095. --- 615,633 ----
  3096.        rtx x;
  3097.   {
  3098.     rtx xops[2];
  3099. !   xops[1] = x;
  3100. !   if (n < 0)
  3101.       {
  3102. !       xops[0] = GEN_INT (-n);
  3103. !       output_asm_insn (AS2 (sub%L0,%0,%1), xops);
  3104.       }
  3105.     else if (n > 0)
  3106.       {
  3107. !       xops[0] = GEN_INT (n);
  3108. !       output_asm_insn (AS2 (add%L0,%0,%1), xops);
  3109.       }
  3110.   }
  3111.   
  3112.   /* Output assembler code to perform a doubleword move insn
  3113.      with operands OPERANDS.  */
  3114.   
  3115. ***************
  3116. *** 1081,1342 ****
  3117.   
  3118.     return "";
  3119.   }
  3120.   
  3121. ! #define MAX_TMPS 2        /* max temporary registers used */
  3122. ! /* Output the appropriate code to move push memory on the stack */
  3123. ! char *
  3124. ! output_move_pushmem (operands, insn, length, tmp_start, n_operands)
  3125. !      rtx operands[];
  3126. !      rtx insn;
  3127. !      int length;
  3128. !      int tmp_start;
  3129. !      int n_operands;
  3130.   {
  3131.   
  3132. !   struct {
  3133. !     char *load;
  3134. !     char *push;
  3135. !     rtx   xops[2];
  3136. !   } tmp_info[MAX_TMPS];
  3137. !   rtx src = operands[1];
  3138. !   int max_tmps = 0;
  3139. !   int offset = 0;
  3140. !   int stack_p = reg_overlap_mentioned_p (stack_pointer_rtx, src);
  3141. !   int stack_offset = 0;
  3142. !   int i, num_tmps;
  3143. !   rtx xops[1];
  3144.   
  3145. !   if (!offsettable_memref_p (src))
  3146. !     fatal_insn ("Source is not offsettable", insn);
  3147.   
  3148. !   if ((length & 3) != 0)
  3149. !     fatal_insn ("Pushing non-word aligned size", insn);
  3150.   
  3151. !   /* Figure out which temporary registers we have available */
  3152. !   for (i = tmp_start; i < n_operands; i++)
  3153. !     {
  3154. !       if (GET_CODE (operands[i]) == REG)
  3155. !     {
  3156. !       if (reg_overlap_mentioned_p (operands[i], src))
  3157. !         continue;
  3158.   
  3159. !       tmp_info[ max_tmps++ ].xops[1] = operands[i];
  3160. !       if (max_tmps == MAX_TMPS)
  3161. !         break;
  3162. !     }
  3163. !     }
  3164.   
  3165. !   if (max_tmps == 0)
  3166. !     for (offset = length - 4; offset >= 0; offset -= 4)
  3167. !       {
  3168. !     xops[0] = adj_offsettable_operand (src, offset + stack_offset);
  3169. !     output_asm_insn (AS1(push%L0,%0), xops);
  3170. !     if (stack_p)
  3171. !       stack_offset += 4;
  3172. !       }
  3173.   
  3174. !   else
  3175. !     for (offset = length - 4; offset >= 0; )
  3176. !       {
  3177. !     for (num_tmps = 0; num_tmps < max_tmps && offset >= 0; num_tmps++)
  3178. !       {
  3179. !         tmp_info[num_tmps].load    = AS2(mov%L0,%0,%1);
  3180. !         tmp_info[num_tmps].push    = AS1(push%L0,%1);
  3181. !         tmp_info[num_tmps].xops[0] = adj_offsettable_operand (src, offset + stack_offset);
  3182. !         offset -= 4;
  3183. !       }
  3184.   
  3185. !     for (i = 0; i < num_tmps; i++)
  3186. !       output_asm_insn (tmp_info[i].load, tmp_info[i].xops);
  3187.   
  3188. !     for (i = 0; i < num_tmps; i++)
  3189. !       output_asm_insn (tmp_info[i].push, tmp_info[i].xops);
  3190.   
  3191. !     if (stack_p)
  3192. !       stack_offset += 4*num_tmps;
  3193. !       }
  3194.   
  3195. !   return "";
  3196.   }
  3197.   
  3198. ! /* Output the appropriate code to move data between two memory locations */
  3199. ! char *
  3200. ! output_move_memory (operands, insn, length, tmp_start, n_operands)
  3201. !      rtx operands[];
  3202. !      rtx insn;
  3203. !      int length;
  3204. !      int tmp_start;
  3205. !      int n_operands;
  3206. ! {
  3207. !   struct {
  3208. !     char *load;
  3209. !     char *store;
  3210. !     rtx   xops[3];
  3211. !   } tmp_info[MAX_TMPS];
  3212. !   rtx dest = operands[0];
  3213. !   rtx src  = operands[1];
  3214. !   rtx qi_tmp = NULL_RTX;
  3215. !   int max_tmps = 0;
  3216. !   int offset = 0;
  3217. !   int i, num_tmps;
  3218. !   rtx xops[3];
  3219. !   if (GET_CODE (dest) == MEM
  3220. !       && GET_CODE (XEXP (dest, 0)) == PRE_INC
  3221. !       && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
  3222. !     return output_move_pushmem (operands, insn, length, tmp_start, n_operands);
  3223. !   if (!offsettable_memref_p (src))
  3224. !     fatal_insn ("Source is not offsettable", insn);
  3225. !   if (!offsettable_memref_p (dest))
  3226. !     fatal_insn ("Destination is not offsettable", insn);
  3227. !   /* Figure out which temporary registers we have available */
  3228. !   for (i = tmp_start; i < n_operands; i++)
  3229. !     {
  3230. !       if (GET_CODE (operands[i]) == REG)
  3231. !     {
  3232. !       if ((length & 1) != 0 && !qi_tmp && QI_REG_P (operands[i]))
  3233. !         qi_tmp = operands[i];
  3234. !       if (reg_overlap_mentioned_p (operands[i], dest))
  3235. !         fatal_insn ("Temporary register overlaps the destination", insn);
  3236. !       if (reg_overlap_mentioned_p (operands[i], src))
  3237. !         fatal_insn ("Temporary register overlaps the source", insn);
  3238. !       tmp_info[ max_tmps++ ].xops[2] = operands[i];
  3239. !       if (max_tmps == MAX_TMPS)
  3240. !         break;
  3241. !     }
  3242. !     }
  3243. !   if (max_tmps == 0)
  3244. !     fatal_insn ("No scratch registers were found to do memory->memory moves", insn);
  3245. !   if ((length & 1) != 0)
  3246. !     {
  3247. !       if (!qi_tmp)
  3248. !     fatal_insn ("No byte register found when moving odd # of bytes.", insn);
  3249. !     }
  3250. !   while (length > 1)
  3251. !     {
  3252. !       for (num_tmps = 0; num_tmps < max_tmps; num_tmps++)
  3253. !     {
  3254. !       if (length >= 4)
  3255. !         {
  3256. !           tmp_info[num_tmps].load    = AS2(mov%L0,%1,%2);
  3257. !           tmp_info[num_tmps].store   = AS2(mov%L0,%2,%0);
  3258. !           tmp_info[num_tmps].xops[0] = adj_offsettable_operand (dest, offset);
  3259. !           tmp_info[num_tmps].xops[1] = adj_offsettable_operand (src, offset);
  3260. !           offset += 4;
  3261. !           length -= 4;
  3262. !         }
  3263. !       else if (length >= 2)
  3264. !         {
  3265. !           tmp_info[num_tmps].load    = AS2(mov%W0,%1,%2);
  3266. !           tmp_info[num_tmps].store   = AS2(mov%W0,%2,%0);
  3267. !           tmp_info[num_tmps].xops[0] = adj_offsettable_operand (dest, offset);
  3268. !           tmp_info[num_tmps].xops[1] = adj_offsettable_operand (src, offset);
  3269. !           offset += 2;
  3270. !           length -= 2;
  3271. !         }
  3272. !       else
  3273. !         break;
  3274. !     }
  3275. !       for (i = 0; i < num_tmps; i++)
  3276. !     output_asm_insn (tmp_info[i].load, tmp_info[i].xops);
  3277. !       for (i = 0; i < num_tmps; i++)
  3278. !     output_asm_insn (tmp_info[i].store, tmp_info[i].xops);
  3279. !     }
  3280. !   if (length == 1)
  3281. !     {
  3282. !       xops[0] = adj_offsettable_operand (dest, offset);
  3283. !       xops[1] = adj_offsettable_operand (src, offset);
  3284. !       xops[2] = qi_tmp;
  3285. !       output_asm_insn (AS2(mov%B0,%1,%2), xops);
  3286. !       output_asm_insn (AS2(mov%B0,%2,%0), xops);
  3287. !     }
  3288. !   return "";
  3289. ! }
  3290. ! int
  3291. ! standard_80387_constant_p (x)
  3292. !      rtx x;
  3293. ! {
  3294. ! #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
  3295. !   REAL_VALUE_TYPE d;
  3296. !   jmp_buf handler;
  3297. !   int is0, is1;
  3298. !   if (setjmp (handler))
  3299. !     return 0;
  3300. !   set_float_handler (handler);
  3301. !   REAL_VALUE_FROM_CONST_DOUBLE (d, x);
  3302. !   is0 = REAL_VALUES_EQUAL (d, dconst0);
  3303. !   is1 = REAL_VALUES_EQUAL (d, dconst1);
  3304. !   set_float_handler (NULL_PTR);
  3305. !   if (is0)
  3306. !     return 1;
  3307. !   if (is1)
  3308. !     return 2;
  3309. !   /* Note that on the 80387, other constants, such as pi,
  3310. !      are much slower to load as standard constants
  3311. !      than to load from doubles in memory!  */
  3312. ! #endif
  3313. !   return 0;
  3314. ! }
  3315. ! char *
  3316. ! output_move_const_single (operands)
  3317. !      rtx *operands;
  3318. ! {
  3319. !   if (FP_REG_P (operands[0]))
  3320. !     {
  3321. !       int conval = standard_80387_constant_p (operands[1]);
  3322. !       if (conval == 1)
  3323. !     return "fldz";
  3324. !       if (conval == 2)
  3325. !     return "fld1";
  3326. !     }
  3327. !   if (GET_CODE (operands[1]) == CONST_DOUBLE)
  3328. !     {
  3329. !       REAL_VALUE_TYPE r; long l;
  3330. !       if (GET_MODE (operands[1]) == XFmode)
  3331. !     abort ();
  3332. !       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
  3333. !       REAL_VALUE_TO_TARGET_SINGLE (r, l);
  3334. !       operands[1] = GEN_INT (l);
  3335. !     }
  3336. !   return singlemove_string (operands);
  3337. ! }
  3338. ! /* Returns 1 if OP is either a symbol reference or a sum of a symbol
  3339. !    reference and a constant.  */
  3340.   
  3341.   int
  3342.   symbolic_operand (op, mode)
  3343. --- 946,1014 ----
  3344.   
  3345.     return "";
  3346.   }
  3347.   
  3348. ! int
  3349. ! standard_80387_constant_p (x)
  3350. !      rtx x;
  3351.   {
  3352. + #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
  3353. +   REAL_VALUE_TYPE d;
  3354. +   jmp_buf handler;
  3355. +   int is0, is1;
  3356.   
  3357. !   if (setjmp (handler))
  3358. !     return 0;
  3359.   
  3360. !   set_float_handler (handler);
  3361. !   REAL_VALUE_FROM_CONST_DOUBLE (d, x);
  3362. !   is0 = REAL_VALUES_EQUAL (d, dconst0);
  3363. !   is1 = REAL_VALUES_EQUAL (d, dconst1);
  3364. !   set_float_handler (NULL_PTR);
  3365.   
  3366. !   if (is0)
  3367. !     return 1;
  3368.   
  3369. !   if (is1)
  3370. !     return 2;
  3371.   
  3372. !   /* Note that on the 80387, other constants, such as pi,
  3373. !      are much slower to load as standard constants
  3374. !      than to load from doubles in memory!  */
  3375. ! #endif
  3376.   
  3377. !   return 0;
  3378. ! }
  3379.   
  3380. ! char *
  3381. ! output_move_const_single (operands)
  3382. !      rtx *operands;
  3383. ! {
  3384. !   if (FP_REG_P (operands[0]))
  3385. !     {
  3386. !       int conval = standard_80387_constant_p (operands[1]);
  3387.   
  3388. !       if (conval == 1)
  3389. !     return "fldz";
  3390.   
  3391. !       if (conval == 2)
  3392. !     return "fld1";
  3393. !     }
  3394. !   if (GET_CODE (operands[1]) == CONST_DOUBLE)
  3395. !     {
  3396. !       REAL_VALUE_TYPE r; long l;
  3397.   
  3398. !       if (GET_MODE (operands[1]) == XFmode)
  3399. !     abort ();
  3400.   
  3401. !       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
  3402. !       REAL_VALUE_TO_TARGET_SINGLE (r, l);
  3403. !       operands[1] = GEN_INT (l);
  3404. !     }
  3405. !   return singlemove_string (operands);
  3406.   }
  3407.   
  3408. ! /* Returns 1 if OP is either a symbol reference or a sum of a symbol
  3409. !    reference and a constant.  */
  3410.   
  3411.   int
  3412.   symbolic_operand (op, mode)
  3413. ***************
  3414. *** 1447,1452 ****
  3415. --- 1119,1229 ----
  3416.     return 0;
  3417.   }
  3418.   
  3419. + /* Return a legitimate reference for ORIG (an address) using the
  3420. +    register REG.  If REG is 0, a new pseudo is generated.
  3421. +    There are three types of references that must be handled:
  3422. +    1. Global data references must load the address from the GOT, via
  3423. +       the PIC reg.  An insn is emitted to do this load, and the reg is
  3424. +       returned.
  3425. +    2. Static data references must compute the address as an offset
  3426. +       from the GOT, whose base is in the PIC reg.  An insn is emitted to
  3427. +       compute the address into a reg, and the reg is returned.  Static
  3428. +       data objects have SYMBOL_REF_FLAG set to differentiate them from
  3429. +       global data objects.
  3430. +    3. Constant pool addresses must be handled special.  They are
  3431. +       considered legitimate addresses, but only if not used with regs.
  3432. +       When printed, the output routines know to print the reference with the
  3433. +       PIC reg, even though the PIC reg doesn't appear in the RTL.
  3434. +    GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
  3435. +    reg also appears in the address (except for constant pool references,
  3436. +    noted above).
  3437. +    "switch" statements also require special handling when generating
  3438. +    PIC code.  See comments by the `casesi' insn in i386.md for details.  */
  3439. + rtx
  3440. + legitimize_pic_address (orig, reg)
  3441. +      rtx orig;
  3442. +      rtx reg;
  3443. + {
  3444. +   rtx addr = orig;
  3445. +   rtx new = orig;
  3446. +   if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
  3447. +     {
  3448. +       if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
  3449. +     reg = new = orig;
  3450. +       else
  3451. +     {
  3452. +       if (reg == 0)
  3453. +         reg = gen_reg_rtx (Pmode);
  3454. +       if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
  3455. +         new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
  3456. +       else
  3457. +         new = gen_rtx (MEM, Pmode,
  3458. +                gen_rtx (PLUS, Pmode,
  3459. +                     pic_offset_table_rtx, orig));
  3460. +       emit_move_insn (reg, new);
  3461. +     }
  3462. +       current_function_uses_pic_offset_table = 1;
  3463. +       return reg;
  3464. +     }
  3465. +   else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
  3466. +     {
  3467. +       rtx base;
  3468. +       if (GET_CODE (addr) == CONST)
  3469. +     {
  3470. +       addr = XEXP (addr, 0);
  3471. +       if (GET_CODE (addr) != PLUS)
  3472. +         abort ();
  3473. +     }
  3474. +       if (XEXP (addr, 0) == pic_offset_table_rtx)
  3475. +     return orig;
  3476. +       if (reg == 0)
  3477. +     reg = gen_reg_rtx (Pmode);
  3478. +       base = legitimize_pic_address (XEXP (addr, 0), reg);
  3479. +       addr = legitimize_pic_address (XEXP (addr, 1),
  3480. +                      base == reg ? NULL_RTX : reg);
  3481. +       if (GET_CODE (addr) == CONST_INT)
  3482. +     return plus_constant (base, INTVAL (addr));
  3483. +       if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
  3484. +     {
  3485. +       base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
  3486. +       addr = XEXP (addr, 1);
  3487. +     }
  3488. +     return gen_rtx (PLUS, Pmode, base, addr);
  3489. +     }
  3490. +   return new;
  3491. + }
  3492. + /* Emit insns to move operands[1] into operands[0].  */
  3493. + void
  3494. + emit_pic_move (operands, mode)
  3495. +      rtx *operands;
  3496. +      enum machine_mode mode;
  3497. + {
  3498. +   rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
  3499. +   if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
  3500. +     operands[1] = (rtx) force_reg (SImode, operands[1]);
  3501. +   else
  3502. +     operands[1] = legitimize_pic_address (operands[1], temp);
  3503. + }
  3504.   /* This function generates the assembly code for function entry.
  3505.      FILE is an stdio stream to output the code to.
  3506.      SIZE is an int: how many units of temporary storage to allocate. */
  3507. ***************
  3508. *** 1540,1546 ****
  3509.     return nregs == 0 || ! frame_pointer_needed;
  3510.   }
  3511.   
  3512.   /* This function generates the assembly code for function exit.
  3513.      FILE is an stdio stream to output the code to.
  3514.      SIZE is an int: how many units of temporary storage to deallocate. */
  3515. --- 1317,1322 ----
  3516. ***************
  3517. *** 1614,1620 ****
  3518.       {
  3519.         /* On i486, mov & pop is faster than "leave". */
  3520.   
  3521. !       if (!TARGET_386)
  3522.       {
  3523.         xops[0] = frame_pointer_rtx;
  3524.         output_asm_insn (AS2 (mov%L2,%0,%2), xops);
  3525. --- 1390,1396 ----
  3526.       {
  3527.         /* On i486, mov & pop is faster than "leave". */
  3528.   
  3529. !       if (TARGET_486)
  3530.       {
  3531.         xops[0] = frame_pointer_rtx;
  3532.         output_asm_insn (AS2 (mov%L2,%0,%2), xops);
  3533. ***************
  3534. *** 1653,3245 ****
  3535.     else
  3536.       output_asm_insn ("ret", xops);
  3537.   }
  3538.   
  3539. ! /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
  3540. !    that is a valid memory address for an instruction.
  3541. !    The MODE argument is the machine mode for the MEM expression
  3542. !    that wants to use this address.
  3543. !    On x86, legitimate addresses are:
  3544. !     base                movl (base),reg
  3545. !     displacement            movl disp,reg
  3546. !     base + displacement        movl disp(base),reg
  3547. !     index + base            movl (base,index),reg
  3548. !     (index + base) + displacement    movl disp(base,index),reg
  3549. !     index*scale            movl (,index,scale),reg
  3550. !     index*scale + disp        movl disp(,index,scale),reg
  3551. !     index*scale + base         movl (base,index,scale),reg
  3552. !     (index*scale + base) + disp    movl disp(base,index,scale),reg
  3553. !     In each case, scale can be 1, 2, 4, 8.  */
  3554. ! /* This is exactly the same as print_operand_addr, except that
  3555. !    it recognizes addresses instead of printing them.
  3556. !    It only recognizes address in canonical form.  LEGITIMIZE_ADDRESS should
  3557. !    convert common non-canonical forms to canonical form so that they will
  3558. !    be recognized.  */
  3559. ! #define ADDR_INVALID(msg,insn)                        \
  3560. ! do {                                    \
  3561. !   if (TARGET_DEBUG_ADDR)                        \
  3562. !     {                                    \
  3563. !       fprintf (stderr, msg);                        \
  3564. !       debug_rtx (insn);                            \
  3565. !     }                                    \
  3566. ! } while (0)
  3567.   
  3568. ! int
  3569. ! legitimate_address_p (mode, addr, strict)
  3570. !      enum machine_mode mode;
  3571. !      register rtx addr;
  3572. !      int strict;
  3573.   {
  3574. !   rtx base  = NULL_RTX;
  3575. !   rtx indx  = NULL_RTX;
  3576. !   rtx scale = NULL_RTX;
  3577. !   rtx disp  = NULL_RTX;
  3578. !   if (TARGET_DEBUG_ADDR)
  3579. !     {
  3580. !       fprintf (stderr,
  3581. !            "\n==========\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
  3582. !            GET_MODE_NAME (mode), strict);
  3583. !       debug_rtx (addr);
  3584. !     }
  3585. !   if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
  3586. !       base = addr;                /* base reg */
  3587.   
  3588. !   else if (GET_CODE (addr) == PLUS)
  3589.       {
  3590. !       rtx op0 = XEXP (addr, 0);
  3591. !       rtx op1 = XEXP (addr, 1);
  3592. !       enum rtx_code code0 = GET_CODE (op0);
  3593. !       enum rtx_code code1 = GET_CODE (op1);
  3594.   
  3595. !       if (code0 == REG || code0 == SUBREG)
  3596.       {
  3597. !       if (code1 == REG || code1 == SUBREG)
  3598. !         {
  3599. !           indx = op0;            /* index + base */
  3600. !           base = op1;
  3601. !         }
  3602. !       else
  3603. !         {
  3604. !           base = op0;            /* base + displacement */
  3605. !           disp = op1;
  3606. !         }
  3607. !     }
  3608. !       else if (code0 == MULT)
  3609. !     {
  3610. !       indx  = XEXP (op0, 0);
  3611. !       scale = XEXP (op0, 1);
  3612. !       if (code1 == REG || code1 == SUBREG)
  3613. !         base = op1;                /* index*scale + base */
  3614. !       else
  3615. !         disp = op1;                /* index*scale + disp */
  3616. !     }
  3617. !       else if (code0 == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
  3618. !     {
  3619. !       indx  = XEXP (XEXP (op0, 0), 0);    /* index*scale + base + disp */
  3620. !       scale = XEXP (XEXP (op0, 0), 1);
  3621. !       base  = XEXP (op0, 1);
  3622. !       disp  = op1;
  3623. !     }
  3624. !       else if (code0 == PLUS)
  3625. !     {
  3626. !       indx = XEXP (op0, 0);            /* index + base + disp */
  3627. !       base = XEXP (op0, 1);
  3628. !       disp = op1;
  3629.       }
  3630.   
  3631.         else
  3632. !     {
  3633. !       ADDR_INVALID ("PLUS subcode is not valid.\n", op0);
  3634. !       return FALSE;
  3635. !     }
  3636. !     }
  3637.   
  3638. !   else if (GET_CODE (addr) == MULT)
  3639. !     {
  3640. !       indx  = XEXP (addr, 0);            /* index*scale */
  3641. !       scale = XEXP (addr, 1);
  3642. !     }
  3643.   
  3644. !   else
  3645. !     disp = addr;                /* displacement */
  3646.   
  3647. !   /* Allow arg pointer and stack pointer as index if there is not scaling */
  3648. !   if (base && indx && !scale
  3649. !       && (indx == arg_pointer_rtx || indx == stack_pointer_rtx))
  3650. !     {
  3651. !       rtx tmp = base;
  3652. !       base = indx;
  3653. !       indx = tmp;
  3654. !     }
  3655.   
  3656. !   /* Validate base register */
  3657. !   /* Don't allow SUBREG's here, it can lead to spill failures when the base
  3658. !      is one word out of a two word structure, which is represented internally
  3659. !      as a DImode int.  */
  3660. !   if (base)
  3661. !     {
  3662. !       if (GET_CODE (base) != REG)
  3663. !     {
  3664. !       ADDR_INVALID ("Base is not a register.\n", base);
  3665. !       return FALSE;
  3666. !     }
  3667.   
  3668. !       if ((strict && !REG_OK_FOR_BASE_STRICT_P (base))
  3669. !       || (!strict && !REG_OK_FOR_BASE_NONSTRICT_P (base)))
  3670.       {
  3671. !       ADDR_INVALID ("Base is not valid.\n", base);
  3672. !       return FALSE;
  3673.       }
  3674. !     }
  3675.   
  3676. !   /* Validate index register */
  3677. !   /* Don't allow SUBREG's here, it can lead to spill failures when the index
  3678. !      is one word out of a two word structure, which is represented internally
  3679. !      as a DImode int.  */
  3680. !   if (indx)
  3681. !     {
  3682. !       if (GET_CODE (indx) != REG)
  3683.       {
  3684. !       ADDR_INVALID ("Index is not a register.\n", indx);
  3685. !       return FALSE;
  3686.       }
  3687. !       if ((strict && !REG_OK_FOR_INDEX_STRICT_P (indx))
  3688. !       || (!strict && !REG_OK_FOR_INDEX_NONSTRICT_P (indx)))
  3689.       {
  3690. !       ADDR_INVALID ("Index is not valid.\n", indx);
  3691. !       return FALSE;
  3692.       }
  3693. !     }
  3694. !   else if (scale)
  3695. !     abort ();                    /* scale w/o index invalid */
  3696. !   /* Validate scale factor */
  3697. !   if (scale)
  3698. !     {
  3699. !       HOST_WIDE_INT value;
  3700.   
  3701. !       if (GET_CODE (scale) != CONST_INT)
  3702. !     {
  3703. !       ADDR_INVALID ("Scale is not valid.\n", scale);
  3704. !       return FALSE;
  3705. !     }
  3706.   
  3707. !       value = INTVAL (scale);
  3708. !       if (value != 1 && value != 2 && value != 4 && value != 8)
  3709. !     {
  3710. !       ADDR_INVALID ("Scale is not a good multiplier.\n", scale);
  3711. !       return FALSE;
  3712. !     }
  3713.       }
  3714.   
  3715. !   /* Validate displacement */
  3716. !   if (disp)
  3717.       {
  3718. !       if (!CONSTANT_ADDRESS_P (disp))
  3719.       {
  3720. !       ADDR_INVALID ("Displacement is not valid.\n", disp);
  3721. !       return FALSE;
  3722. !     }
  3723.   
  3724. !       if (GET_CODE (disp) == CONST_DOUBLE)
  3725. !     {
  3726. !       ADDR_INVALID ("Displacement is a const_double.\n", disp);
  3727. !       return FALSE;
  3728. !     }
  3729.   
  3730. !       if (flag_pic && SYMBOLIC_CONST (disp) && base != pic_offset_table_rtx
  3731. !       && (indx != pic_offset_table_rtx || scale != NULL_RTX))
  3732. !     {
  3733. !       ADDR_INVALID ("Displacement is an invalid pic reference.\n", disp);
  3734. !       return FALSE;
  3735. !     }
  3736.   
  3737. !       if (HALF_PIC_P () && HALF_PIC_ADDRESS_P (disp)
  3738. !       && (base != NULL_RTX || indx != NULL_RTX))
  3739. !     {
  3740. !       ADDR_INVALID ("Displacement is an invalid half-pic reference.\n", disp);
  3741. !       return FALSE;
  3742. !     }
  3743. !     }
  3744.   
  3745. !   if (TARGET_DEBUG_ADDR)
  3746. !     fprintf (stderr, "Address is valid.\n");
  3747.   
  3748. !   /* Everything looks valid, return true */
  3749. !   return TRUE;
  3750. ! }
  3751.   
  3752. ! /* Return a legitimate reference for ORIG (an address) using the
  3753. !    register REG.  If REG is 0, a new pseudo is generated.
  3754.   
  3755. !    There are three types of references that must be handled:
  3756.   
  3757. !    1. Global data references must load the address from the GOT, via
  3758. !       the PIC reg.  An insn is emitted to do this load, and the reg is
  3759. !       returned.
  3760.   
  3761. !    2. Static data references must compute the address as an offset
  3762. !       from the GOT, whose base is in the PIC reg.  An insn is emitted to
  3763. !       compute the address into a reg, and the reg is returned.  Static
  3764. !       data objects have SYMBOL_REF_FLAG set to differentiate them from
  3765. !       global data objects.
  3766.   
  3767. !    3. Constant pool addresses must be handled special.  They are
  3768. !       considered legitimate addresses, but only if not used with regs.
  3769. !       When printed, the output routines know to print the reference with the
  3770. !       PIC reg, even though the PIC reg doesn't appear in the RTL.
  3771.   
  3772. !    GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
  3773. !    reg also appears in the address (except for constant pool references,
  3774. !    noted above).
  3775.   
  3776. !    "switch" statements also require special handling when generating
  3777. !    PIC code.  See comments by the `casesi' insn in i386.md for details.  */
  3778.   
  3779. ! rtx
  3780. ! legitimize_pic_address (orig, reg)
  3781. !      rtx orig;
  3782. !      rtx reg;
  3783. ! {
  3784. !   rtx addr = orig;
  3785. !   rtx new = orig;
  3786.   
  3787. !   if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
  3788. !     {
  3789. !       if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
  3790. !     reg = new = orig;
  3791. !       else
  3792. !     {
  3793. !       if (reg == 0)
  3794. !         reg = gen_reg_rtx (Pmode);
  3795.   
  3796. !       if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
  3797. !           || GET_CODE (addr) == LABEL_REF)
  3798. !         new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
  3799. !       else
  3800. !         new = gen_rtx (MEM, Pmode,
  3801. !                gen_rtx (PLUS, Pmode,
  3802. !                     pic_offset_table_rtx, orig));
  3803.   
  3804. !       emit_move_insn (reg, new);
  3805. !     }
  3806. !       current_function_uses_pic_offset_table = 1;
  3807. !       return reg;
  3808. !     }
  3809. !   else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
  3810. !     {
  3811. !       rtx base;
  3812.   
  3813. !       if (GET_CODE (addr) == CONST)
  3814. !     {
  3815. !       addr = XEXP (addr, 0);
  3816. !       if (GET_CODE (addr) != PLUS)
  3817. !         abort ();
  3818. !     }
  3819.   
  3820. !       if (XEXP (addr, 0) == pic_offset_table_rtx)
  3821. !     return orig;
  3822.   
  3823. !       if (reg == 0)
  3824. !     reg = gen_reg_rtx (Pmode);
  3825. !       base = legitimize_pic_address (XEXP (addr, 0), reg);
  3826. !       addr = legitimize_pic_address (XEXP (addr, 1),
  3827. !                      base == reg ? NULL_RTX : reg);
  3828. !       if (GET_CODE (addr) == CONST_INT)
  3829. !     return plus_constant (base, INTVAL (addr));
  3830. !       if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
  3831.       {
  3832. !       base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
  3833. !       addr = XEXP (addr, 1);
  3834.       }
  3835. !     return gen_rtx (PLUS, Pmode, base, addr);
  3836.       }
  3837. -   return new;
  3838.   }
  3839.   
  3840. ! /* Emit insns to move operands[1] into operands[0].  */
  3841.   
  3842.   void
  3843. ! emit_pic_move (operands, mode)
  3844. !      rtx *operands;
  3845. !      enum machine_mode mode;
  3846. ! {
  3847. !   rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
  3848. !   if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
  3849. !     operands[1] = (rtx) force_reg (SImode, operands[1]);
  3850. !   else
  3851. !     operands[1] = legitimize_pic_address (operands[1], temp);
  3852. ! }
  3853. ! /* Try machine-dependent ways of modifying an illegitimate address
  3854. !    to be legitimate.  If we find one, return the new, valid address.
  3855. !    This macro is used in only one place: `memory_address' in explow.c.
  3856. !    OLDX is the address as it was before break_out_memory_refs was called.
  3857. !    In some cases it is useful to look at this to decide what needs to be done.
  3858. !    MODE and WIN are passed so that this macro can use
  3859. !    GO_IF_LEGITIMATE_ADDRESS.
  3860. !    It is always safe for this macro to do nothing.  It exists to recognize
  3861. !    opportunities to optimize the output.
  3862. !    For the 80386, we handle X+REG by loading X into a register R and
  3863. !    using R+REG.  R will go in a general reg and indexing will be used.
  3864. !    However, if REG is a broken-out memory address or multiplication,
  3865. !    nothing needs to be done because REG can certainly go in a general reg.
  3866. !    When -fpic is used, special handling is needed for symbolic references.
  3867. !    See comments by legitimize_pic_address in i386.c for details.  */
  3868. ! rtx
  3869. ! legitimize_address (x, oldx, mode)
  3870. !      register rtx x;
  3871. !      register rtx oldx;
  3872. !      enum machine_mode mode;
  3873.   {
  3874. !   int changed = 0;
  3875. !   unsigned log;
  3876. !   if (TARGET_DEBUG_ADDR)
  3877. !     {
  3878. !       fprintf (stderr, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n", GET_MODE_NAME (mode));
  3879. !       debug_rtx (x);
  3880. !     }
  3881. !   if (flag_pic && SYMBOLIC_CONST (x))
  3882. !     return legitimize_pic_address (x, 0);
  3883.   
  3884. !   /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
  3885. !   if (GET_CODE (x) == ASHIFT
  3886. !       && GET_CODE (XEXP (x, 1)) == CONST_INT
  3887. !       && (log = (unsigned)exact_log2 (INTVAL (XEXP (x, 1)))) < 4)
  3888.       {
  3889. !       changed = 1;
  3890. !       x = gen_rtx (MULT, Pmode,
  3891. !            force_reg (Pmode, XEXP (x, 0)),
  3892. !            GEN_INT (1 << log));
  3893. !     }
  3894.   
  3895. !   if (GET_CODE (x) == PLUS)
  3896. !     {
  3897. !       /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
  3898. !       if (GET_CODE (XEXP (x, 0)) == ASHIFT
  3899. !       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
  3900. !       && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) < 4)
  3901.       {
  3902. !       changed = 1;
  3903. !       XEXP (x, 0) = gen_rtx (MULT, Pmode,
  3904. !                  force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
  3905. !                  GEN_INT (1 << log));
  3906.       }
  3907. !       if (GET_CODE (XEXP (x, 1)) == ASHIFT
  3908. !       && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
  3909. !       && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1)))) < 4)
  3910.       {
  3911. !       changed = 1;
  3912. !       XEXP (x, 1) = gen_rtx (MULT, Pmode,
  3913. !                  force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
  3914. !                  GEN_INT (1 << log));
  3915.       }
  3916. !       /* Put multiply first if it isn't already */
  3917. !       if (GET_CODE (XEXP (x, 1)) == MULT)
  3918.       {
  3919. !       rtx tmp = XEXP (x, 0);
  3920. !       XEXP (x, 0) = XEXP (x, 1);
  3921. !       XEXP (x, 1) = tmp;
  3922. !       changed = 1;
  3923.       }
  3924. !       /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
  3925. !      into (plus (plus (mult (reg) (const)) (reg)) (const)).  This can be
  3926. !      created by virtual register instantiation, register elimination, and
  3927. !      similar optimizations.  */
  3928. !       if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
  3929.       {
  3930. !       changed = 1;
  3931. !       x = gen_rtx (PLUS, Pmode,
  3932. !                gen_rtx (PLUS, Pmode, XEXP (x, 0), XEXP (XEXP (x, 1), 0)),
  3933. !                XEXP (XEXP (x, 1), 1));
  3934.       }
  3935.   
  3936. !       /* Canonicalize (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
  3937. !      into (plus (plus (mult (reg) (const)) (reg)) (const)).  */
  3938. !       else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
  3939. !            && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
  3940. !            && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
  3941. !            && CONSTANT_P (XEXP (x, 1)))
  3942.       {
  3943. !       rtx constant, other;
  3944.   
  3945. !       if (GET_CODE (XEXP (x, 1)) == CONST_INT)
  3946. !         {
  3947. !           constant = XEXP (x, 1);
  3948. !           other = XEXP (XEXP (XEXP (x, 0), 1), 1);
  3949. !         }
  3950. !       else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
  3951.           {
  3952. !           constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
  3953. !           other = XEXP (x, 1);
  3954.           }
  3955. -       else
  3956. -         constant = 0;
  3957.   
  3958. !       if (constant)
  3959.           {
  3960. !           changed = 1;
  3961. !           x = gen_rtx (PLUS, Pmode,
  3962. !                gen_rtx (PLUS, Pmode, XEXP (XEXP (x, 0), 0),
  3963. !                     XEXP (XEXP (XEXP (x, 0), 1), 0)),
  3964. !                plus_constant (other, INTVAL (constant)));
  3965.           }
  3966. -     }
  3967. -       if (changed && legitimate_address_p (mode, x, FALSE))
  3968. -     return x;
  3969.   
  3970. !       if (GET_CODE (XEXP (x, 0)) == MULT)
  3971. !     {
  3972. !       changed = 1;
  3973. !       XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
  3974. !     }
  3975.   
  3976. !       if (GET_CODE (XEXP (x, 1)) == MULT)
  3977. !     {
  3978. !       changed = 1;
  3979. !       XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
  3980. !     }
  3981.   
  3982. !       if (changed
  3983. !       && GET_CODE (XEXP (x, 1)) == REG
  3984. !       && GET_CODE (XEXP (x, 0)) == REG)
  3985. !     return x;
  3986.   
  3987. !       if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
  3988. !     {
  3989. !       changed = 1;
  3990. !       x = legitimize_pic_address (x, 0);
  3991.       }
  3992.   
  3993. !       if (changed && legitimate_address_p (mode, x, FALSE))
  3994. !     return x;
  3995. !       if (GET_CODE (XEXP (x, 0)) == REG)
  3996. !     {
  3997. !       register rtx temp = gen_reg_rtx (Pmode);
  3998. !       register rtx val  = force_operand (XEXP (x, 1), temp);
  3999. !       if (val != temp)
  4000. !         emit_move_insn (temp, val);
  4001. !       XEXP (x, 1) = temp;
  4002. !       return x;
  4003. !     }
  4004.   
  4005. !       else if (GET_CODE (XEXP (x, 1)) == REG)
  4006.       {
  4007. !       register rtx temp = gen_reg_rtx (Pmode);
  4008. !       register rtx val  = force_operand (XEXP (x, 0), temp);
  4009. !       if (val != temp)
  4010. !         emit_move_insn (temp, val);
  4011. !       XEXP (x, 0) = temp;
  4012. !       return x;
  4013.       }
  4014.       }
  4015. -   return x;
  4016.   }
  4017.   
  4018. ! /* Print an integer constant expression in assembler syntax.  Addition
  4019. !    and subtraction are the only arithmetic that may appear in these
  4020. !    expressions.  FILE is the stdio stream to write to, X is the rtx, and
  4021. !    CODE is the operand print code from the output string.  */
  4022.   
  4023. ! static void
  4024. ! output_pic_addr_const (file, x, code)
  4025. !      FILE *file;
  4026. !      rtx x;
  4027. !      int code;
  4028. ! {
  4029. !   char buf[256];
  4030.   
  4031. !   switch (GET_CODE (x))
  4032.       {
  4033. !     case PC:
  4034. !       if (flag_pic)
  4035. !     putc ('.', file);
  4036. !       else
  4037. !     abort ();
  4038. !       break;
  4039. !     case SYMBOL_REF:
  4040. !     case LABEL_REF:
  4041. !       if (GET_CODE (x) == SYMBOL_REF)
  4042. !     assemble_name (file, XSTR (x, 0));
  4043. !       else
  4044.       {
  4045. !       ASM_GENERATE_INTERNAL_LABEL (buf, "L",
  4046. !                        CODE_LABEL_NUMBER (XEXP (x, 0)));
  4047. !       assemble_name (asm_out_file, buf);
  4048.       }
  4049.   
  4050. !       if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
  4051. !     fprintf (file, "@GOTOFF(%%ebx)");
  4052. !       else if (code == 'P')
  4053. !     fprintf (file, "@PLT");
  4054. !       else if (GET_CODE (x) == LABEL_REF)
  4055. !     fprintf (file, "@GOTOFF");
  4056. !       else if (! SYMBOL_REF_FLAG (x))
  4057. !     fprintf (file, "@GOT");
  4058. !       else
  4059. !     fprintf (file, "@GOTOFF");
  4060. !       break;
  4061. !     case CODE_LABEL:
  4062. !       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
  4063. !       assemble_name (asm_out_file, buf);
  4064. !       break;
  4065. !     case CONST_INT:
  4066. !       fprintf (file, "%d", INTVAL (x));
  4067. !       break;
  4068. !     case CONST:
  4069. !       /* This used to output parentheses around the expression,
  4070. !      but that does not work on the 386 (either ATT or BSD assembler).  */
  4071. !       output_pic_addr_const (file, XEXP (x, 0), code);
  4072. !       break;
  4073.   
  4074. !     case CONST_DOUBLE:
  4075. !       if (GET_MODE (x) == VOIDmode)
  4076.       {
  4077. !       /* We can use %d if the number is <32 bits and positive.  */
  4078. !       if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
  4079. !         fprintf (file, "0x%x%08x",
  4080. !              CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
  4081.         else
  4082. !         fprintf (file, "%d", CONST_DOUBLE_LOW (x));
  4083.       }
  4084. !       else
  4085. !     /* We can't handle floating point constants;
  4086. !        PRINT_OPERAND must handle them.  */
  4087. !     output_operand_lossage ("floating constant misused");
  4088. !       break;
  4089.   
  4090. !     case PLUS:
  4091. !       /* Some assemblers need integer constants to appear last (eg masm).  */
  4092. !       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
  4093.       {
  4094. !       output_pic_addr_const (file, XEXP (x, 1), code);
  4095. !       if (INTVAL (XEXP (x, 0)) >= 0)
  4096. !         fprintf (file, "+");
  4097. !       output_pic_addr_const (file, XEXP (x, 0), code);
  4098.       }
  4099. !       else
  4100.       {
  4101. !       output_pic_addr_const (file, XEXP (x, 0), code);
  4102. !       if (INTVAL (XEXP (x, 1)) >= 0)
  4103. !         fprintf (file, "+");
  4104. !       output_pic_addr_const (file, XEXP (x, 1), code);
  4105.       }
  4106. !       break;
  4107.   
  4108.       case MINUS:
  4109. !       output_pic_addr_const (file, XEXP (x, 0), code);
  4110. !       fprintf (file, "-");
  4111. !       output_pic_addr_const (file, XEXP (x, 1), code);
  4112. !       break;
  4113.   
  4114.       default:
  4115. !       output_operand_lossage ("invalid expression as operand");
  4116.       }
  4117.   }
  4118. - /* Meaning of CODE:
  4119. -    f -- float insn (print a CONST_DOUBLE as a float rather than in hex).
  4120. -    D,L,W,B,Q,S -- print the opcode suffix for specified size of operand.
  4121. -    R -- print the prefix for register names.
  4122. -    z -- print the opcode suffix for the size of the current operand.
  4123. -    * -- print a star (in certain assembler syntax)
  4124. -    w -- print the operand as if it's a "word" (HImode) even if it isn't.
  4125. -    c -- don't print special prefixes before constant operands.
  4126. -    J -- print the appropriate jump operand.
  4127. - */
  4128.   
  4129. ! void
  4130. ! print_operand (file, x, code)
  4131. !      FILE *file;
  4132. !      rtx x;
  4133. !      int code;
  4134.   {
  4135. !   if (code)
  4136.       {
  4137. !       switch (code)
  4138. !     {
  4139. !     case '*':
  4140. !       if (USE_STAR)
  4141. !         putc ('*', file);
  4142. !       return;
  4143.   
  4144. !     case 'L':
  4145. !       PUT_OP_SIZE (code, 'l', file);
  4146. !       return;
  4147.   
  4148. !     case 'W':
  4149. !       PUT_OP_SIZE (code, 'w', file);
  4150. !       return;
  4151.   
  4152. !     case 'B':
  4153. !       PUT_OP_SIZE (code, 'b', file);
  4154. !       return;
  4155.   
  4156. !     case 'Q':
  4157. !       PUT_OP_SIZE (code, 'l', file);
  4158. !       return;
  4159. !     case 'S':
  4160. !       PUT_OP_SIZE (code, 's', file);
  4161. !       return;
  4162.   
  4163. !     case 'T':
  4164. !       PUT_OP_SIZE (code, 't', file);
  4165. !       return;
  4166.   
  4167. !     case 'z':
  4168. !       /* 387 opcodes don't get size suffixes if the operands are
  4169. !          registers. */
  4170.   
  4171. !       if (STACK_REG_P (x))
  4172. !         return;
  4173.   
  4174. !       /* this is the size of op from size of operand */
  4175. !       switch (GET_MODE_SIZE (GET_MODE (x)))
  4176. !         {
  4177. !         case 1:
  4178. !           PUT_OP_SIZE ('B', 'b', file);
  4179. !           return;
  4180.   
  4181. !         case 2:
  4182. !           PUT_OP_SIZE ('W', 'w', file);
  4183. !           return;
  4184.   
  4185. !         case 4:
  4186. !           if (GET_MODE (x) == SFmode)
  4187. !         {
  4188. !           PUT_OP_SIZE ('S', 's', file);
  4189. !           return;
  4190. !         }
  4191. !           else
  4192. !         PUT_OP_SIZE ('L', 'l', file);
  4193. !           return;
  4194.   
  4195. !         case 12:
  4196. !           PUT_OP_SIZE ('T', 't', file);
  4197. !           return;
  4198.   
  4199. !         case 8:
  4200. !           if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
  4201. !         {
  4202. ! #ifdef GAS_MNEMONICS
  4203. !           PUT_OP_SIZE ('Q', 'q', file);
  4204. !           return;
  4205. ! #else
  4206. !           PUT_OP_SIZE ('Q', 'l', file);    /* Fall through */
  4207. ! #endif
  4208. !         }
  4209.   
  4210. !           PUT_OP_SIZE ('Q', 'l', file);
  4211. !           return;
  4212. !         }
  4213.   
  4214. !     case 'b':
  4215. !     case 'w':
  4216. !     case 'k':
  4217. !     case 'h':
  4218. !     case 'y':
  4219. !     case 'P':
  4220. !       break;
  4221.   
  4222. !     case 'J':
  4223. !       switch (GET_CODE (x))
  4224. !         {
  4225. !           /* These conditions are appropriate for testing the result
  4226. !          of an arithmetic operation, not for a compare operation.
  4227. !              Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume
  4228. !          CC_Z_IN_NOT_C false and not floating point.  */
  4229. !         case NE:  fputs ("jne", file); return;
  4230. !         case EQ:  fputs ("je",  file); return;
  4231. !         case GE:  fputs ("jns", file); return;
  4232. !         case LT:  fputs ("js",  file); return;
  4233. !         case GEU: fputs ("jmp", file); return;
  4234. !         case GTU: fputs ("jne",  file); return;
  4235. !         case LEU: fputs ("je", file); return;
  4236. !         case LTU: fputs ("#branch never",  file); return;
  4237.   
  4238. !         /* no matching branches for GT nor LE */
  4239. !         }
  4240. !       abort ();
  4241.   
  4242. !     default:
  4243. !       {
  4244. !         char str[50];
  4245.   
  4246. !         sprintf (str, "invalid operand code `%c'", code);
  4247. !         output_operand_lossage (str);
  4248. !       }
  4249. !     }
  4250. !     }
  4251. !   if (GET_CODE (x) == REG)
  4252. !     {
  4253. !       PRINT_REG (x, code, file);
  4254. !     }
  4255. !   else if (GET_CODE (x) == MEM)
  4256. !     {
  4257. !       PRINT_PTR (x, file);
  4258. !       if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
  4259. !     {
  4260. !       if (flag_pic)
  4261. !         output_pic_addr_const (file, XEXP (x, 0), code);
  4262. !       else
  4263. !         output_addr_const (file, XEXP (x, 0));
  4264. !     }
  4265. !       else
  4266. !     output_address (XEXP (x, 0));
  4267. !     }
  4268. !   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
  4269. !     {
  4270. !       REAL_VALUE_TYPE r; long l;
  4271. !       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
  4272. !       REAL_VALUE_TO_TARGET_SINGLE (r, l);
  4273. !       PRINT_IMMED_PREFIX (file);
  4274. !       fprintf (file, "0x%x", l);
  4275. !     }
  4276. !  /* These float cases don't actually occur as immediate operands. */
  4277. !  else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
  4278. !     {
  4279. !       REAL_VALUE_TYPE r; char dstr[30];
  4280. !       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
  4281. !       REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
  4282. !       fprintf (file, "%s", dstr);
  4283. !     }
  4284. !   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
  4285. !     {
  4286. !       REAL_VALUE_TYPE r; char dstr[30];
  4287. !       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
  4288. !       REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
  4289. !       fprintf (file, "%s", dstr);
  4290. !     }
  4291. !   else 
  4292.       {
  4293. !       if (code != 'P')
  4294.       {
  4295. !       if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
  4296. !         PRINT_IMMED_PREFIX (file);
  4297. !       else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
  4298. !            || GET_CODE (x) == LABEL_REF)
  4299. !         PRINT_OFFSET_PREFIX (file);
  4300.       }
  4301. -       if (flag_pic)
  4302. -     output_pic_addr_const (file, x, code);
  4303. -       else
  4304. -     output_addr_const (file, x);
  4305. -     }
  4306. - }
  4307. - /* Print a memory operand whose address is ADDR.  */
  4308. - void
  4309. - print_operand_address (file, addr)
  4310. -      FILE *file;
  4311. -      register rtx addr;
  4312. - {
  4313. -   register rtx reg1, reg2, breg, ireg;
  4314. -   rtx offset;
  4315.   
  4316. !   switch (GET_CODE (addr))
  4317. !     {
  4318. !     case REG:
  4319. !       ADDR_BEG (file);
  4320. !       fprintf (file, "%se", RP);
  4321. !       fputs (hi_reg_name[REGNO (addr)], file);
  4322. !       ADDR_END (file);
  4323. !       break;
  4324.   
  4325. !     case PLUS:
  4326. !       reg1 = 0;
  4327. !       reg2 = 0;
  4328. !       ireg = 0;
  4329. !       breg = 0;
  4330. !       offset = 0;
  4331. !       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
  4332.       {
  4333. !       offset = XEXP (addr, 0);
  4334. !       addr = XEXP (addr, 1);
  4335.       }
  4336. !       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
  4337.       {
  4338. !       offset = XEXP (addr, 1);
  4339. !       addr = XEXP (addr, 0);
  4340.       }
  4341. !       if (GET_CODE (addr) != PLUS) ;
  4342. !       else if (GET_CODE (XEXP (addr, 0)) == MULT)
  4343. !     {
  4344. !       reg1 = XEXP (addr, 0);
  4345. !       addr = XEXP (addr, 1);
  4346. !     }
  4347. !       else if (GET_CODE (XEXP (addr, 1)) == MULT)
  4348. !     {
  4349. !       reg1 = XEXP (addr, 1);
  4350. !       addr = XEXP (addr, 0);
  4351. !     }
  4352. !       else if (GET_CODE (XEXP (addr, 0)) == REG)
  4353. !     {
  4354. !       reg1 = XEXP (addr, 0);
  4355. !       addr = XEXP (addr, 1);
  4356. !     }
  4357. !       else if (GET_CODE (XEXP (addr, 1)) == REG)
  4358. !     {
  4359. !       reg1 = XEXP (addr, 1);
  4360. !       addr = XEXP (addr, 0);
  4361. !     }
  4362. !       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
  4363. !     {
  4364. !       if (reg1 == 0) reg1 = addr;
  4365. !       else reg2 = addr;
  4366. !       addr = 0;
  4367. !     }
  4368. !       if (offset != 0)
  4369.       {
  4370. !       if (addr != 0) abort ();
  4371. !       addr = offset;
  4372.       }
  4373. !       if ((reg1 && GET_CODE (reg1) == MULT)
  4374. !       || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
  4375.       {
  4376. !       breg = reg2;
  4377. !       ireg = reg1;
  4378.       }
  4379. !       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
  4380.       {
  4381. !       breg = reg1;
  4382. !       ireg = reg2;
  4383.       }
  4384.   
  4385. !       if (ireg != 0 || breg != 0)
  4386. !     {
  4387. !       int scale = 1;
  4388.   
  4389. !       if (addr != 0)
  4390. !         {
  4391. !           if (flag_pic)
  4392. !         output_pic_addr_const (file, addr, 0);
  4393.   
  4394. !           else if (GET_CODE (addr) == LABEL_REF)
  4395. !         output_asm_label (addr);
  4396.   
  4397. !           else
  4398. !         output_addr_const (file, addr);
  4399. !         }
  4400.   
  4401. !         if (ireg != 0 && GET_CODE (ireg) == MULT)
  4402. !         {
  4403. !           scale = INTVAL (XEXP (ireg, 1));
  4404. !           ireg = XEXP (ireg, 0);
  4405. !         }
  4406.   
  4407. !       /* The stack pointer can only appear as a base register,
  4408. !          never an index register, so exchange the regs if it is wrong. */
  4409.   
  4410. !       if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
  4411. !         {
  4412. !           rtx tmp;
  4413.   
  4414. !           tmp = breg;
  4415. !           breg = ireg;
  4416. !           ireg = tmp;
  4417. !         }
  4418.   
  4419. !       /* output breg+ireg*scale */
  4420. !       PRINT_B_I_S (breg, ireg, scale, file);
  4421. !       break;
  4422. !     }
  4423.   
  4424. !     case MULT:
  4425. !       {
  4426. !     int scale;
  4427. !     if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
  4428. !       {
  4429. !         scale = INTVAL (XEXP (addr, 0));
  4430. !         ireg = XEXP (addr, 1);
  4431. !       }
  4432. !     else
  4433. !       {
  4434. !         scale = INTVAL (XEXP (addr, 1));
  4435. !         ireg = XEXP (addr, 0);
  4436. !       }
  4437. !     output_addr_const (file, const0_rtx);
  4438. !     PRINT_B_I_S ((rtx) 0, ireg, scale, file);
  4439. !       }
  4440. !       break;
  4441.   
  4442. !     default:
  4443. !       if (GET_CODE (addr) == CONST_INT
  4444. !       && INTVAL (addr) < 0x8000
  4445. !       && INTVAL (addr) >= -0x8000)
  4446. !     fprintf (file, "%d", INTVAL (addr));
  4447.         else
  4448. !     {
  4449. !       if (flag_pic)
  4450. !         output_pic_addr_const (file, addr, 0);
  4451. !       else
  4452. !         output_addr_const (file, addr);
  4453. !     }
  4454.       }
  4455.   }
  4456.   
  4457. ! /* Set the cc_status for the results of an insn whose pattern is EXP.
  4458. !    On the 80386, we assume that only test and compare insns, as well
  4459. !    as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT,
  4460. !    ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
  4461. !    Also, we assume that jumps, moves and sCOND don't affect the condition
  4462. !    codes.  All else clobbers the condition codes, by assumption.
  4463.   
  4464. !    We assume that ALL integer add, minus, etc. instructions effect the
  4465. !    condition codes.  This MUST be consistent with i386.md.
  4466.   
  4467. !    We don't record any float test or compare - the redundant test &
  4468. !    compare check in final.c does not handle stack-like regs correctly. */
  4469.   
  4470. ! void
  4471. ! notice_update_cc (exp)
  4472. !      rtx exp;
  4473. ! {
  4474. !   if (GET_CODE (exp) == SET)
  4475.       {
  4476. !       /* Jumps do not alter the cc's.  */
  4477. !       if (SET_DEST (exp) == pc_rtx)
  4478. !     return;
  4479. !       /* Moving register or memory into a register:
  4480. !      it doesn't alter the cc's, but it might invalidate
  4481. !      the RTX's which we remember the cc's came from.
  4482. !      (Note that moving a constant 0 or 1 MAY set the cc's).  */
  4483. !       if (REG_P (SET_DEST (exp))
  4484. !       && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
  4485. !           || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
  4486. !     {
  4487. !       if (cc_status.value1
  4488. !           && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
  4489. !         cc_status.value1 = 0;
  4490. !       if (cc_status.value2
  4491. !           && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
  4492. !         cc_status.value2 = 0;
  4493. !       return;
  4494. !     }
  4495. !       /* Moving register into memory doesn't alter the cc's.
  4496. !      It may invalidate the RTX's which we remember the cc's came from.  */
  4497. !       if (GET_CODE (SET_DEST (exp)) == MEM
  4498. !       && (REG_P (SET_SRC (exp))
  4499. !           || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
  4500. !     {
  4501. !       if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
  4502. !         cc_status.value1 = 0;
  4503. !       if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
  4504. !         cc_status.value2 = 0;
  4505. !       return;
  4506. !     }
  4507. !       /* Function calls clobber the cc's.  */
  4508. !       else if (GET_CODE (SET_SRC (exp)) == CALL)
  4509. !     {
  4510. !       CC_STATUS_INIT;
  4511. !       return;
  4512. !     }
  4513. !       /* Tests and compares set the cc's in predictable ways.  */
  4514. !       else if (SET_DEST (exp) == cc0_rtx)
  4515. !     {
  4516. !       CC_STATUS_INIT;
  4517. !       cc_status.value1 = SET_SRC (exp);
  4518. !       return;
  4519. !     }
  4520. !       /* Certain instructions effect the condition codes. */
  4521. !       else if (GET_MODE (SET_SRC (exp)) == SImode
  4522. !            || GET_MODE (SET_SRC (exp)) == HImode
  4523. !            || GET_MODE (SET_SRC (exp)) == QImode)
  4524. !     switch (GET_CODE (SET_SRC (exp)))
  4525. !       {
  4526. !       case ASHIFTRT: case LSHIFTRT:
  4527. !       case ASHIFT:
  4528. !         /* Shifts on the 386 don't set the condition codes if the
  4529. !            shift count is zero. */
  4530. !         if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
  4531. !           {
  4532. !         CC_STATUS_INIT;
  4533. !         break;
  4534. !           }
  4535. !         /* We assume that the CONST_INT is non-zero (this rtx would
  4536. !            have been deleted if it were zero. */
  4537.   
  4538. !       case PLUS: case MINUS: case NEG:
  4539. !       case AND: case IOR: case XOR:
  4540. !         cc_status.flags = CC_NO_OVERFLOW;
  4541. !         cc_status.value1 = SET_SRC (exp);
  4542. !         cc_status.value2 = SET_DEST (exp);
  4543. !         break;
  4544.   
  4545. !       default:
  4546. !         CC_STATUS_INIT;
  4547. !       }
  4548. !       else
  4549. !     {
  4550. !       CC_STATUS_INIT;
  4551. !     }
  4552.       }
  4553. !   else if (GET_CODE (exp) == PARALLEL
  4554. !        && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
  4555.       {
  4556. !       if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
  4557. !     return;
  4558. !       if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
  4559. !     {
  4560. !       CC_STATUS_INIT;
  4561. !       if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
  4562. !         cc_status.flags |= CC_IN_80387;
  4563. !       else
  4564. !         cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
  4565. !       return;
  4566. !     }
  4567. !       CC_STATUS_INIT;
  4568.       }
  4569.     else
  4570.       {
  4571. !       CC_STATUS_INIT;
  4572.       }
  4573.   }
  4574. - /* Split one or more DImode RTL references into pairs of SImode
  4575. -    references.  The RTL can be REG, offsettable MEM, integer constant, or
  4576. -    CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
  4577. -    split and "num" is its length.  lo_half and hi_half are output arrays
  4578. -    that parallel "operands". */
  4579.   
  4580.   void
  4581. ! split_di (operands, num, lo_half, hi_half)
  4582. !      rtx operands[];
  4583. !      int num;
  4584. !      rtx lo_half[], hi_half[];
  4585.   {
  4586. !   while (num--)
  4587. !     {
  4588. !       if (GET_CODE (operands[num]) == REG)
  4589. !     {
  4590. !       lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
  4591. !       hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
  4592. !     }
  4593. !       else if (CONSTANT_P (operands[num]))
  4594. !     {
  4595. !       split_double (operands[num], &lo_half[num], &hi_half[num]);
  4596. !     }
  4597. !       else if (offsettable_memref_p (operands[num]))
  4598. !     {
  4599. !       lo_half[num] = operands[num];
  4600. !       hi_half[num] = adj_offsettable_operand (operands[num], 4);
  4601. !     }
  4602. !       else
  4603. !     abort();
  4604. !     }
  4605.   }
  4606. - /* Return 1 if this is a valid binary operation on a 387.
  4607. -    OP is the expression matched, and MODE is its mode. */
  4608.   
  4609. ! int
  4610. ! binary_387_op (op, mode)
  4611. !     register rtx op;
  4612. !     enum machine_mode mode;
  4613.   {
  4614. !   if (mode != VOIDmode && mode != GET_MODE (op))
  4615. !     return 0;
  4616.   
  4617. !   switch (GET_CODE (op))
  4618. !     {
  4619. !     case PLUS:
  4620. !     case MINUS:
  4621. !     case MULT:
  4622. !     case DIV:
  4623. !       return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
  4624.   
  4625. !     default:
  4626. !       return 0;
  4627. !     }
  4628.   }
  4629.   
  4630. ! /* Return 1 if this is a valid shift or rotate operation on a 386.
  4631. !    OP is the expression matched, and MODE is its mode. */
  4632.   
  4633. ! int
  4634. ! shift_op (op, mode)
  4635. !     register rtx op;
  4636. !     enum machine_mode mode;
  4637.   {
  4638. !   rtx operand = XEXP (op, 0);
  4639.   
  4640. !   if (mode != VOIDmode && mode != GET_MODE (op))
  4641. !     return 0;
  4642.   
  4643. -   if (GET_MODE (operand) != GET_MODE (op)
  4644. -       || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
  4645. -     return 0;
  4646.   
  4647. !   return (GET_CODE (op) == ASHIFT
  4648. !       || GET_CODE (op) == ASHIFTRT
  4649. !       || GET_CODE (op) == LSHIFTRT
  4650. !       || GET_CODE (op) == ROTATE
  4651. !       || GET_CODE (op) == ROTATERT);
  4652.   }
  4653.   
  4654. ! /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
  4655. !    MODE is not used.  */
  4656. ! int
  4657. ! VOIDmode_compare_op (op, mode)
  4658.       register rtx op;
  4659.       enum machine_mode mode;
  4660.   {
  4661. !   return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
  4662.   }
  4663. - /* Output code to perform a 387 binary operation in INSN, one of PLUS,
  4664. -    MINUS, MULT or DIV.  OPERANDS are the insn operands, where operands[3]
  4665. -    is the expression of the binary operation.  The output may either be
  4666. -    emitted here, or returned to the caller, like all output_* functions.
  4667.   
  4668. !    There is no guarantee that the operands are the same mode, as they
  4669. !    might be within FLOAT or FLOAT_EXTEND expressions. */
  4670.   
  4671. ! char *
  4672. ! output_387_binary_op (insn, operands)
  4673. !      rtx insn;
  4674. !      rtx *operands;
  4675.   {
  4676. !   rtx temp;
  4677. !   char *base_op;
  4678. !   static char buf[100];
  4679.   
  4680. !   switch (GET_CODE (operands[3]))
  4681.       {
  4682. !     case PLUS:
  4683. !       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
  4684. !       || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
  4685. !     base_op = "fiadd";
  4686. !       else
  4687. !     base_op = "fadd";
  4688. !       break;
  4689.   
  4690. !     case MINUS:
  4691. !       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
  4692. !       || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
  4693. !     base_op = "fisub";
  4694. !       else
  4695. !     base_op = "fsub";
  4696.         break;
  4697.   
  4698. !     case MULT:
  4699. !       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
  4700. !       || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
  4701. !     base_op = "fimul";
  4702. !       else
  4703. !     base_op = "fmul";
  4704. !       break;
  4705.   
  4706. !     case DIV:
  4707. !       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
  4708. !       || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
  4709. !     base_op = "fidiv";
  4710. !       else
  4711. !     base_op = "fdiv";
  4712. !       break;
  4713.   
  4714. !     default:
  4715. !       abort ();
  4716.       }
  4717. !   strcpy (buf, base_op);
  4718. !   switch (GET_CODE (operands[3]))
  4719.       {
  4720. !     case MULT:
  4721. !     case PLUS:
  4722. !       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
  4723.       {
  4724. !       temp = operands[2];
  4725. !       operands[2] = operands[1];
  4726. !       operands[1] = temp;
  4727.       }
  4728. !       if (GET_CODE (operands[2]) == MEM)
  4729. !     return strcat (buf, AS1 (%z2,%2));
  4730. !       if (NON_STACK_REG_P (operands[1]))
  4731.       {
  4732. !       output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
  4733. !       RET;
  4734.       }
  4735. !       else if (NON_STACK_REG_P (operands[2]))
  4736.       {
  4737. !       output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
  4738. !       RET;
  4739.       }
  4740. -       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
  4741. -     return strcat (buf, AS2 (p,%2,%0));
  4742. -       if (STACK_TOP_P (operands[0]))
  4743. -     return strcat (buf, AS2C (%y2,%0));
  4744.         else
  4745. -     return strcat (buf, AS2C (%2,%0));
  4746. -     case MINUS:
  4747. -     case DIV:
  4748. -       if (GET_CODE (operands[1]) == MEM)
  4749. -     return strcat (buf, AS1 (r%z1,%1));
  4750. -       if (GET_CODE (operands[2]) == MEM)
  4751. -     return strcat (buf, AS1 (%z2,%2));
  4752. -       if (NON_STACK_REG_P (operands[1]))
  4753.       {
  4754. !       output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
  4755. !       RET;
  4756.       }
  4757. !       else if (NON_STACK_REG_P (operands[2]))
  4758.       {
  4759. !       output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
  4760. !       RET;
  4761.       }
  4762. !       if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
  4763. !     abort ();
  4764. !       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
  4765. !     return strcat (buf, AS2 (rp,%2,%0));
  4766. !       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
  4767. !     return strcat (buf, AS2 (p,%1,%0));
  4768. !       if (STACK_TOP_P (operands[0]))
  4769.       {
  4770. !       if (STACK_TOP_P (operands[1]))
  4771. !         return strcat (buf, AS2C (%y2,%0));
  4772.         else
  4773. !         return strcat (buf, AS2 (r,%y1,%0));
  4774.       }
  4775. !       else if (STACK_TOP_P (operands[1]))
  4776. !     return strcat (buf, AS2C (%1,%0));
  4777. !       else
  4778. !     return strcat (buf, AS2 (r,%2,%0));
  4779. !     default:
  4780. !       abort ();
  4781.       }
  4782.   }
  4783. - /* Output code for INSN to convert a float to a signed int.  OPERANDS
  4784. -    are the insn operands.  The output may be SFmode or DFmode and the
  4785. -    input operand may be SImode or DImode.  As a special case, make sure
  4786. -    that the 387 stack top dies if the output mode is DImode, because the
  4787. -    hardware requires this.  */
  4788.   
  4789. ! char *
  4790. ! output_fix_trunc (insn, operands)
  4791. !      rtx insn;
  4792. !      rtx *operands;
  4793.   {
  4794. !   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  4795. !   rtx xops[2];
  4796.   
  4797. !   if (! STACK_TOP_P (operands[1]) ||
  4798. !       (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
  4799. !     abort ();
  4800. !   xops[0] = GEN_INT (12);
  4801. !   xops[1] = operands[4];
  4802. !   output_asm_insn (AS1 (fnstc%W2,%2), operands);
  4803. !   output_asm_insn (AS2 (mov%L2,%2,%4), operands);
  4804. !   output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
  4805. !   output_asm_insn (AS2 (mov%L4,%4,%3), operands);
  4806. !   output_asm_insn (AS1 (fldc%W3,%3), operands);
  4807. !   if (NON_STACK_REG_P (operands[0]))
  4808. !     output_to_reg (operands[0], stack_top_dies);
  4809. !   else if (GET_CODE (operands[0]) == MEM)
  4810.       {
  4811. !       if (stack_top_dies)
  4812. !     output_asm_insn (AS1 (fistp%z0,%0), operands);
  4813.         else
  4814. !     output_asm_insn (AS1 (fist%z0,%0), operands);
  4815.       }
  4816. !   else
  4817. !     abort ();
  4818. !   return AS1 (fldc%W2,%2);
  4819.   }
  4820. - /* Output code for INSN to compare OPERANDS.  The two operands might
  4821. -    not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
  4822. -    expression.  If the compare is in mode CCFPEQmode, use an opcode that
  4823. -    will not fault if a qNaN is present. */
  4824.   
  4825. ! char *
  4826. ! output_float_compare (insn, operands)
  4827. !      rtx insn;
  4828. !      rtx *operands;
  4829.   {
  4830. !   int stack_top_dies;
  4831. !   rtx body = XVECEXP (PATTERN (insn), 0, 0);
  4832. !   int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
  4833. !   if (! STACK_TOP_P (operands[0]))
  4834. !     abort ();
  4835. !   stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  4836. !   if (STACK_REG_P (operands[1])
  4837. !       && stack_top_dies
  4838. !       && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
  4839. !       && REGNO (operands[1]) != FIRST_STACK_REG)
  4840. !     {
  4841. !       /* If both the top of the 387 stack dies, and the other operand
  4842. !      is also a stack register that dies, then this must be a
  4843. !      `fcompp' float compare */
  4844. !       if (unordered_compare)
  4845. !     output_asm_insn ("fucompp", operands);
  4846. !       else
  4847. !     output_asm_insn ("fcompp", operands);
  4848. !     }
  4849. !   else
  4850.       {
  4851. !       static char buf[100];
  4852. !       /* Decide if this is the integer or float compare opcode, or the
  4853. !      unordered float compare. */
  4854. !       if (unordered_compare)
  4855. !     strcpy (buf, "fucom");
  4856. !       else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
  4857. !     strcpy (buf, "fcom");
  4858. !       else
  4859. !     strcpy (buf, "ficom");
  4860. !       /* Modify the opcode if the 387 stack is to be popped. */
  4861. !       if (stack_top_dies)
  4862. !     strcat (buf, "p");
  4863. !       if (NON_STACK_REG_P (operands[1]))
  4864. !     output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
  4865. !       else
  4866. !         output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
  4867. !     }
  4868.   
  4869. !   /* Now retrieve the condition code. */
  4870.   
  4871. !   return output_fp_cc0_set (insn);
  4872.   }
  4873. - /* Output opcodes to transfer the results of FP compare or test INSN
  4874. -    from the FPU to the CPU flags.  If TARGET_IEEE_FP, ensure that if the
  4875. -    result of the compare or test is unordered, no comparison operator
  4876. -    succeeds except NE.  Return an output template, if any.  */
  4877.   
  4878. ! char *
  4879. ! output_fp_cc0_set (insn)
  4880. !      rtx insn;
  4881.   {
  4882. !   rtx xops[3];
  4883. !   rtx unordered_label;
  4884. !   rtx next;
  4885. !   enum rtx_code code;
  4886.   
  4887. !   xops[0] = gen_rtx (REG, HImode, 0);
  4888. !   output_asm_insn (AS1 (fnsts%W0,%0), xops);
  4889.   
  4890. !   if (! TARGET_IEEE_FP)
  4891. !     return "sahf";
  4892.   
  4893. -   next = next_cc0_user (insn);
  4894. -   if (next == NULL_RTX)
  4895. -     abort ();
  4896.   
  4897. !   if (GET_CODE (next) == JUMP_INSN
  4898. !       && GET_CODE (PATTERN (next)) == SET
  4899. !       && SET_DEST (PATTERN (next)) == pc_rtx
  4900. !       && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
  4901. !     {
  4902. !       code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
  4903. !     }
  4904. !   else if (GET_CODE (PATTERN (next)) == SET)
  4905.       {
  4906. !       code = GET_CODE (SET_SRC (PATTERN (next)));
  4907.       }
  4908. !   else
  4909. !     abort ();
  4910.   
  4911. !   xops[0] = gen_rtx (REG, QImode, 0);
  4912.   
  4913. !   switch (code)
  4914.       {
  4915. !     case GT:
  4916. !       xops[1] = GEN_INT (0x45);
  4917. !       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
  4918. !       /* je label */
  4919. !       break;
  4920.   
  4921. -     case LT:
  4922. -       xops[1] = GEN_INT (0x45);
  4923. -       xops[2] = GEN_INT (0x01);
  4924. -       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
  4925. -       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
  4926. -       /* je label */
  4927. -       break;
  4928.   
  4929. !     case GE:
  4930. !       xops[1] = GEN_INT (0x05);
  4931. !       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
  4932. !       /* je label */
  4933. !       break;
  4934.   
  4935. -     case LE:
  4936. -       xops[1] = GEN_INT (0x45);
  4937. -       xops[2] = GEN_INT (0x40);
  4938. -       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
  4939. -       output_asm_insn (AS1 (dec%B0,%h0), xops);
  4940. -       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
  4941. -       /* jb label */
  4942. -       break;
  4943.   
  4944. -     case EQ:
  4945. -       xops[1] = GEN_INT (0x45);
  4946. -       xops[2] = GEN_INT (0x40);
  4947. -       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
  4948. -       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
  4949. -       /* je label */
  4950. -       break;
  4951.   
  4952. -     case NE:
  4953. -       xops[1] = GEN_INT (0x44);
  4954. -       xops[2] = GEN_INT (0x40);
  4955. -       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
  4956. -       output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
  4957. -       /* jne label */
  4958. -       break;
  4959.   
  4960. !     case GTU:
  4961. !     case LTU:
  4962. !     case GEU:
  4963. !     case LEU:
  4964. !     default:
  4965. !       abort ();
  4966.       }
  4967. !   RET;
  4968.   }
  4969. - #define MAX_386_STACK_LOCALS 2
  4970.   
  4971. ! static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
  4972.   
  4973. ! /* Define the structure for the machine field in struct function.  */
  4974. ! struct machine_function
  4975.   {
  4976. !   rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
  4977. ! };
  4978.   
  4979. - /* Functions to save and restore i386_stack_locals.
  4980. -    These will be called, via pointer variables,
  4981. -    from push_function_context and pop_function_context.  */
  4982.   
  4983. ! void
  4984. ! save_386_machine_status (p)
  4985. !      struct function *p;
  4986.   {
  4987. !   p->machine = (struct machine_function *) xmalloc (sizeof i386_stack_locals);
  4988. !   bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals,
  4989. !      sizeof i386_stack_locals);
  4990.   }
  4991.   
  4992. ! void
  4993. ! restore_386_machine_status (p)
  4994. !      struct function *p;
  4995.   {
  4996. !   bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals,
  4997. !      sizeof i386_stack_locals);
  4998. !   free (p->machine);
  4999.   }
  5000.   
  5001. - /* Clear stack slot assignments remembered from previous functions.
  5002. -    This is called from INIT_EXPANDERS once before RTL is emitted for each
  5003. -    function.  */
  5004.   
  5005. ! void
  5006. ! clear_386_stack_locals ()
  5007.   {
  5008. !   enum machine_mode mode;
  5009. !   int n;
  5010.   
  5011. !   for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
  5012. !        mode = (enum machine_mode) ((int) mode + 1))
  5013. !     for (n = 0; n < MAX_386_STACK_LOCALS; n++)
  5014. !       i386_stack_locals[(int) mode][n] = NULL_RTX;
  5015.   
  5016. !   /* Arrange to save and restore i386_stack_locals around nested functions.  */
  5017. !   save_machine_status = save_386_machine_status;
  5018. !   restore_machine_status = restore_386_machine_status;
  5019. ! }
  5020.   
  5021. ! /* Return a MEM corresponding to a stack slot with mode MODE.
  5022. !    Allocate a new slot if necessary.
  5023.   
  5024. !    The RTL for a function can have several slots available: N is
  5025. !    which slot to use.  */
  5026.   
  5027. - rtx
  5028. - assign_386_stack_local (mode, n)
  5029. -      enum machine_mode mode;
  5030. -      int n;
  5031. - {
  5032. -   if (n < 0 || n >= MAX_386_STACK_LOCALS)
  5033. -     abort ();
  5034.   
  5035. !   if (i386_stack_locals[(int) mode][n] == NULL_RTX)
  5036. !     i386_stack_locals[(int) mode][n]
  5037. !       = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
  5038.   
  5039. !   return i386_stack_locals[(int) mode][n];
  5040.   }
  5041. --- 1429,3510 ----
  5042.     else
  5043.       output_asm_insn ("ret", xops);
  5044.   }
  5045.   
  5046. ! /* Print an integer constant expression in assembler syntax.  Addition
  5047. !    and subtraction are the only arithmetic that may appear in these
  5048. !    expressions.  FILE is the stdio stream to write to, X is the rtx, and
  5049. !    CODE is the operand print code from the output string.  */
  5050.   
  5051. ! static void
  5052. ! output_pic_addr_const (file, x, code)
  5053. !      FILE *file;
  5054. !      rtx x;
  5055. !      int code;
  5056.   {
  5057. !   char buf[256];
  5058.   
  5059. !   switch (GET_CODE (x))
  5060.       {
  5061. !     case PC:
  5062. !       if (flag_pic)
  5063. !     putc ('.', file);
  5064. !       else
  5065. !     abort ();
  5066. !       break;
  5067.   
  5068. !     case SYMBOL_REF:
  5069. !     case LABEL_REF:
  5070. !       if (GET_CODE (x) == SYMBOL_REF)
  5071. !     assemble_name (file, XSTR (x, 0));
  5072. !       else
  5073.       {
  5074. !       ASM_GENERATE_INTERNAL_LABEL (buf, "L",
  5075. !                        CODE_LABEL_NUMBER (XEXP (x, 0)));
  5076. !       assemble_name (asm_out_file, buf);
  5077.       }
  5078.   
  5079. +       if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
  5080. +     fprintf (file, "@GOTOFF(%%ebx)");
  5081. +       else if (code == 'P')
  5082. +     fprintf (file, "@PLT");
  5083. +       else if (GET_CODE (x) == LABEL_REF || ! SYMBOL_REF_FLAG (x))
  5084. +     fprintf (file, "@GOT");
  5085.         else
  5086. !     fprintf (file, "@GOTOFF");
  5087.   
  5088. !       break;
  5089.   
  5090. !     case CODE_LABEL:
  5091. !       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
  5092. !       assemble_name (asm_out_file, buf);
  5093. !       break;
  5094.   
  5095. !     case CONST_INT:
  5096. !       fprintf (file, "%d", INTVAL (x));
  5097. !       break;
  5098.   
  5099. !     case CONST:
  5100. !       /* This used to output parentheses around the expression,
  5101. !      but that does not work on the 386 (either ATT or BSD assembler).  */
  5102. !       output_pic_addr_const (file, XEXP (x, 0), code);
  5103. !       break;
  5104.   
  5105. !     case CONST_DOUBLE:
  5106. !       if (GET_MODE (x) == VOIDmode)
  5107.       {
  5108. !       /* We can use %d if the number is <32 bits and positive.  */
  5109. !       if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
  5110. !         fprintf (file, "0x%x%08x",
  5111. !              CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
  5112. !       else
  5113. !         fprintf (file, "%d", CONST_DOUBLE_LOW (x));
  5114.       }
  5115. !       else
  5116. !     /* We can't handle floating point constants;
  5117. !        PRINT_OPERAND must handle them.  */
  5118. !     output_operand_lossage ("floating constant misused");
  5119. !       break;
  5120.   
  5121. !     case PLUS:
  5122. !       /* Some assemblers need integer constants to appear last (eg masm).  */
  5123. !       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
  5124.       {
  5125. !       output_pic_addr_const (file, XEXP (x, 1), code);
  5126. !       if (INTVAL (XEXP (x, 0)) >= 0)
  5127. !         fprintf (file, "+");
  5128. !       output_pic_addr_const (file, XEXP (x, 0), code);
  5129.       }
  5130. !       else
  5131.       {
  5132. !       output_pic_addr_const (file, XEXP (x, 0), code);
  5133. !       if (INTVAL (XEXP (x, 1)) >= 0)
  5134. !         fprintf (file, "+");
  5135. !       output_pic_addr_const (file, XEXP (x, 1), code);
  5136.       }
  5137. !       break;
  5138.   
  5139. !     case MINUS:
  5140. !       output_pic_addr_const (file, XEXP (x, 0), code);
  5141. !       fprintf (file, "-");
  5142. !       output_pic_addr_const (file, XEXP (x, 1), code);
  5143. !       break;
  5144.   
  5145. !     default:
  5146. !       output_operand_lossage ("invalid expression as operand");
  5147.       }
  5148. + }
  5149. + /* Meaning of CODE:
  5150. +    f -- float insn (print a CONST_DOUBLE as a float rather than in hex).
  5151. +    D,L,W,B,Q,S -- print the opcode suffix for specified size of operand.
  5152. +    R -- print the prefix for register names.
  5153. +    z -- print the opcode suffix for the size of the current operand.
  5154. +    * -- print a star (in certain assembler syntax)
  5155. +    w -- print the operand as if it's a "word" (HImode) even if it isn't.
  5156. +    c -- don't print special prefixes before constant operands.
  5157. +    J -- print the appropriate jump operand.
  5158. + */
  5159.   
  5160. ! void
  5161. ! print_operand (file, x, code)
  5162. !      FILE *file;
  5163. !      rtx x;
  5164. !      int code;
  5165. ! {
  5166. !   if (code)
  5167.       {
  5168. !       switch (code)
  5169.       {
  5170. !     case '*':
  5171. !       if (USE_STAR)
  5172. !         putc ('*', file);
  5173. !       return;
  5174.   
  5175. !     case 'L':
  5176. !       PUT_OP_SIZE (code, 'l', file);
  5177. !       return;
  5178.   
  5179. !     case 'W':
  5180. !       PUT_OP_SIZE (code, 'w', file);
  5181. !       return;
  5182.   
  5183. !     case 'B':
  5184. !       PUT_OP_SIZE (code, 'b', file);
  5185. !       return;
  5186.   
  5187. !     case 'Q':
  5188. !       PUT_OP_SIZE (code, 'l', file);
  5189. !       return;
  5190.   
  5191. !     case 'S':
  5192. !       PUT_OP_SIZE (code, 's', file);
  5193. !       return;
  5194.   
  5195. !     case 'T':
  5196. !       PUT_OP_SIZE (code, 't', file);
  5197. !       return;
  5198.   
  5199. !     case 'z':
  5200. !       /* 387 opcodes don't get size suffixes if the operands are
  5201. !          registers. */
  5202.   
  5203. !       if (STACK_REG_P (x))
  5204. !         return;
  5205.   
  5206. !       /* this is the size of op from size of operand */
  5207. !       switch (GET_MODE_SIZE (GET_MODE (x)))
  5208. !         {
  5209. !         case 1:
  5210. !           PUT_OP_SIZE ('B', 'b', file);
  5211. !           return;
  5212.   
  5213. !         case 2:
  5214. !           PUT_OP_SIZE ('W', 'w', file);
  5215. !           return;
  5216.   
  5217. !         case 4:
  5218. !           if (GET_MODE (x) == SFmode)
  5219. !         {
  5220. !           PUT_OP_SIZE ('S', 's', file);
  5221. !           return;
  5222. !         }
  5223. !           else
  5224. !         PUT_OP_SIZE ('L', 'l', file);
  5225. !           return;
  5226.   
  5227. !         case 12:
  5228. !           PUT_OP_SIZE ('T', 't', file);
  5229. !           return;
  5230.   
  5231. !         case 8:
  5232. !           if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
  5233. !         {
  5234. ! #ifdef GAS_MNEMONICS
  5235. !           PUT_OP_SIZE ('Q', 'q', file);
  5236. !           return;
  5237. ! #else
  5238. !           PUT_OP_SIZE ('Q', 'l', file);    /* Fall through */
  5239. ! #endif
  5240. !         }
  5241.   
  5242. !           PUT_OP_SIZE ('Q', 'l', file);
  5243. !           return;
  5244. !         }
  5245.   
  5246. !     case 'b':
  5247. !     case 'w':
  5248. !     case 'k':
  5249. !     case 'h':
  5250. !     case 'y':
  5251. !     case 'P':
  5252. !       break;
  5253.   
  5254. !     case 'J':
  5255. !       switch (GET_CODE (x))
  5256. !         {
  5257. !           /* These conditions are appropriate for testing the result
  5258. !          of an arithmetic operation, not for a compare operation.
  5259. !              Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume
  5260. !          CC_Z_IN_NOT_C false and not floating point.  */
  5261. !         case NE:  fputs ("jne", file); return;
  5262. !         case EQ:  fputs ("je",  file); return;
  5263. !         case GE:  fputs ("jns", file); return;
  5264. !         case LT:  fputs ("js",  file); return;
  5265. !         case GEU: fputs ("jmp", file); return;
  5266. !         case GTU: fputs ("jne",  file); return;
  5267. !         case LEU: fputs ("je", file); return;
  5268. !         case LTU: fputs ("#branch never",  file); return;
  5269.   
  5270. !         /* no matching branches for GT nor LE */
  5271. !         }
  5272. !       abort ();
  5273.   
  5274. !     default:
  5275. !       {
  5276. !         char str[50];
  5277.   
  5278. !         sprintf (str, "invalid operand code `%c'", code);
  5279. !         output_operand_lossage (str);
  5280. !       }
  5281. !     }
  5282. !     }
  5283. !   if (GET_CODE (x) == REG)
  5284. !     {
  5285. !       PRINT_REG (x, code, file);
  5286. !     }
  5287. !   else if (GET_CODE (x) == MEM)
  5288. !     {
  5289. !       PRINT_PTR (x, file);
  5290. !       if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
  5291.       {
  5292. !       if (flag_pic)
  5293. !         output_pic_addr_const (file, XEXP (x, 0), code);
  5294. !       else
  5295. !         output_addr_const (file, XEXP (x, 0));
  5296.       }
  5297. !       else
  5298. !     output_address (XEXP (x, 0));
  5299. !     }
  5300. !   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
  5301. !     {
  5302. !       REAL_VALUE_TYPE r; long l;
  5303. !       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
  5304. !       REAL_VALUE_TO_TARGET_SINGLE (r, l);
  5305. !       PRINT_IMMED_PREFIX (file);
  5306. !       fprintf (file, "0x%x", l);
  5307. !     }
  5308. !  /* These float cases don't actually occur as immediate operands. */
  5309. !  else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
  5310. !     {
  5311. !       REAL_VALUE_TYPE r; char dstr[30];
  5312. !       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
  5313. !       REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
  5314. !       fprintf (file, "%s", dstr);
  5315. !     }
  5316. !   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
  5317. !     {
  5318. !       REAL_VALUE_TYPE r; char dstr[30];
  5319. !       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
  5320. !       REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
  5321. !       fprintf (file, "%s", dstr);
  5322. !     }
  5323. !   else 
  5324. !     {
  5325. !       if (code != 'P')
  5326. !     {
  5327. !       if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
  5328. !         PRINT_IMMED_PREFIX (file);
  5329. !       else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
  5330. !            || GET_CODE (x) == LABEL_REF)
  5331. !         PRINT_OFFSET_PREFIX (file);
  5332. !     }
  5333. !       if (flag_pic)
  5334. !     output_pic_addr_const (file, x, code);
  5335. !       else
  5336. !     output_addr_const (file, x);
  5337.       }
  5338.   }
  5339.   
  5340. ! /* Print a memory operand whose address is ADDR.  */
  5341.   
  5342.   void
  5343. ! print_operand_address (file, addr)
  5344. !      FILE *file;
  5345. !      register rtx addr;
  5346.   {
  5347. !   register rtx reg1, reg2, breg, ireg;
  5348. !   rtx offset;
  5349.   
  5350. !   switch (GET_CODE (addr))
  5351.       {
  5352. !     case REG:
  5353. !       ADDR_BEG (file);
  5354. !       fprintf (file, "%se", RP);
  5355. !       fputs (hi_reg_name[REGNO (addr)], file);
  5356. !       ADDR_END (file);
  5357. !       break;
  5358.   
  5359. !     case PLUS:
  5360. !       reg1 = 0;
  5361. !       reg2 = 0;
  5362. !       ireg = 0;
  5363. !       breg = 0;
  5364. !       offset = 0;
  5365. !       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
  5366.       {
  5367. !       offset = XEXP (addr, 0);
  5368. !       addr = XEXP (addr, 1);
  5369.       }
  5370. !       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
  5371.       {
  5372. !       offset = XEXP (addr, 1);
  5373. !       addr = XEXP (addr, 0);
  5374.       }
  5375. !       if (GET_CODE (addr) != PLUS) ;
  5376. !       else if (GET_CODE (XEXP (addr, 0)) == MULT)
  5377.       {
  5378. !       reg1 = XEXP (addr, 0);
  5379. !       addr = XEXP (addr, 1);
  5380.       }
  5381. !       else if (GET_CODE (XEXP (addr, 1)) == MULT)
  5382. !     {
  5383. !       reg1 = XEXP (addr, 1);
  5384. !       addr = XEXP (addr, 0);
  5385. !     }
  5386. !       else if (GET_CODE (XEXP (addr, 0)) == REG)
  5387. !     {
  5388. !       reg1 = XEXP (addr, 0);
  5389. !       addr = XEXP (addr, 1);
  5390. !     }
  5391. !       else if (GET_CODE (XEXP (addr, 1)) == REG)
  5392. !     {
  5393. !       reg1 = XEXP (addr, 1);
  5394. !       addr = XEXP (addr, 0);
  5395. !     }
  5396. !       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
  5397. !     {
  5398. !       if (reg1 == 0) reg1 = addr;
  5399. !       else reg2 = addr;
  5400. !       addr = 0;
  5401. !     }
  5402. !       if (offset != 0)
  5403. !     {
  5404. !       if (addr != 0) abort ();
  5405. !       addr = offset;
  5406. !     }
  5407. !       if ((reg1 && GET_CODE (reg1) == MULT)
  5408. !       || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
  5409. !     {
  5410. !       breg = reg2;
  5411. !       ireg = reg1;
  5412. !     }
  5413. !       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
  5414.       {
  5415. !       breg = reg1;
  5416. !       ireg = reg2;
  5417.       }
  5418.   
  5419. !       if (ireg != 0 || breg != 0)
  5420.       {
  5421. !       int scale = 1;
  5422.   
  5423. !       if (addr != 0)
  5424.           {
  5425. !           if (GET_CODE (addr) == LABEL_REF)
  5426. !         output_asm_label (addr);
  5427. !           else
  5428. !         {
  5429. !           if (flag_pic)
  5430. !             output_pic_addr_const (file, addr, 0);
  5431. !           else
  5432. !             output_addr_const (file, addr);
  5433. !         }
  5434.           }
  5435.   
  5436. !         if (ireg != 0 && GET_CODE (ireg) == MULT)
  5437.           {
  5438. !           scale = INTVAL (XEXP (ireg, 1));
  5439. !           ireg = XEXP (ireg, 0);
  5440.           }
  5441.   
  5442. !       /* The stack pointer can only appear as a base register,
  5443. !          never an index register, so exchange the regs if it is wrong. */
  5444.   
  5445. !       if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
  5446. !         {
  5447. !           rtx tmp;
  5448.   
  5449. !           tmp = breg;
  5450. !           breg = ireg;
  5451. !           ireg = tmp;
  5452. !         }
  5453.   
  5454. !       /* output breg+ireg*scale */
  5455. !       PRINT_B_I_S (breg, ireg, scale, file);
  5456. !       break;
  5457.       }
  5458.   
  5459. !     case MULT:
  5460. !       {
  5461. !     int scale;
  5462. !     if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
  5463. !       {
  5464. !         scale = INTVAL (XEXP (addr, 0));
  5465. !         ireg = XEXP (addr, 1);
  5466. !       }
  5467. !     else
  5468. !       {
  5469. !         scale = INTVAL (XEXP (addr, 1));
  5470. !         ireg = XEXP (addr, 0);
  5471. !       }
  5472. !     output_addr_const (file, const0_rtx);
  5473. !     PRINT_B_I_S ((rtx) 0, ireg, scale, file);
  5474. !       }
  5475. !       break;
  5476.   
  5477. !     default:
  5478. !       if (GET_CODE (addr) == CONST_INT
  5479. !       && INTVAL (addr) < 0x8000
  5480. !       && INTVAL (addr) >= -0x8000)
  5481. !     fprintf (file, "%d", INTVAL (addr));
  5482. !       else
  5483.       {
  5484. !       if (flag_pic)
  5485. !         output_pic_addr_const (file, addr, 0);
  5486. !       else
  5487. !         output_addr_const (file, addr);
  5488.       }
  5489.       }
  5490.   }
  5491.   
  5492. ! /* Set the cc_status for the results of an insn whose pattern is EXP.
  5493. !    On the 80386, we assume that only test and compare insns, as well
  5494. !    as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT, LSHIFT,
  5495. !    ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
  5496. !    Also, we assume that jumps, moves and sCOND don't affect the condition
  5497. !    codes.  All else clobbers the condition codes, by assumption.
  5498.   
  5499. !    We assume that ALL integer add, minus, etc. instructions effect the
  5500. !    condition codes.  This MUST be consistent with i386.md.
  5501.   
  5502. !    We don't record any float test or compare - the redundant test &
  5503. !    compare check in final.c does not handle stack-like regs correctly. */
  5504. ! void
  5505. ! notice_update_cc (exp)
  5506. !      rtx exp;
  5507. ! {
  5508. !   if (GET_CODE (exp) == SET)
  5509.       {
  5510. !       /* Jumps do not alter the cc's.  */
  5511. !       if (SET_DEST (exp) == pc_rtx)
  5512. !     return;
  5513. ! #ifdef IS_STACK_MODE
  5514. !       /* intel1 
  5515. !          Moving into a memory of stack_mode may have been moved
  5516. !          in between the use and set of cc0 by loop_spl(). So
  5517. !          old value of cc.status must be retained */
  5518. !       if(GET_CODE(SET_DEST(exp))==MEM 
  5519. !          && IS_STACK_MODE(GET_MODE(SET_DEST(exp))))
  5520. !         {
  5521. !           return;
  5522. !         }
  5523. ! #endif
  5524. !       /* Moving register or memory into a register:
  5525. !      it doesn't alter the cc's, but it might invalidate
  5526. !      the RTX's which we remember the cc's came from.
  5527. !      (Note that moving a constant 0 or 1 MAY set the cc's).  */
  5528. !       if (REG_P (SET_DEST (exp))
  5529. !       && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
  5530. !           || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
  5531.       {
  5532. !       if (cc_status.value1
  5533. !           && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
  5534. !         cc_status.value1 = 0;
  5535. !       if (cc_status.value2
  5536. !           && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
  5537. !         cc_status.value2 = 0;
  5538. !       return;
  5539.       }
  5540. +       /* Moving register into memory doesn't alter the cc's.
  5541. +      It may invalidate the RTX's which we remember the cc's came from.  */
  5542. +       if (GET_CODE (SET_DEST (exp)) == MEM
  5543. +       && (REG_P (SET_SRC (exp))
  5544. +           || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
  5545. +     {
  5546. +       if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
  5547. +         cc_status.value1 = 0;
  5548. +       if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
  5549. +         cc_status.value2 = 0;
  5550. +       return;
  5551. +     }
  5552. +       /* Function calls clobber the cc's.  */
  5553. +       else if (GET_CODE (SET_SRC (exp)) == CALL)
  5554. +     {
  5555. +       CC_STATUS_INIT;
  5556. +       return;
  5557. +     }
  5558. +       /* Tests and compares set the cc's in predictable ways.  */
  5559. +       else if (SET_DEST (exp) == cc0_rtx)
  5560. +     {
  5561. +       CC_STATUS_INIT;
  5562. +       cc_status.value1 = SET_SRC (exp);
  5563. +       return;
  5564. +     }
  5565. +       /* Certain instructions effect the condition codes. */
  5566. +       else if (GET_MODE (SET_SRC (exp)) == SImode
  5567. +            || GET_MODE (SET_SRC (exp)) == HImode
  5568. +            || GET_MODE (SET_SRC (exp)) == QImode)
  5569. +     switch (GET_CODE (SET_SRC (exp)))
  5570. +       {
  5571. +       case ASHIFTRT: case LSHIFTRT:
  5572. +       case ASHIFT: case LSHIFT:
  5573. +         /* Shifts on the 386 don't set the condition codes if the
  5574. +            shift count is zero. */
  5575. +         if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
  5576. +           {
  5577. +         CC_STATUS_INIT;
  5578. +         break;
  5579. +           }
  5580. +         /* We assume that the CONST_INT is non-zero (this rtx would
  5581. +            have been deleted if it were zero. */
  5582.   
  5583. !       case PLUS: case MINUS: case NEG:
  5584. !       case AND: case IOR: case XOR:
  5585. !         cc_status.flags = CC_NO_OVERFLOW;
  5586. !         cc_status.value1 = SET_SRC (exp);
  5587. !         cc_status.value2 = SET_DEST (exp);
  5588. !         break;
  5589.   
  5590. !       default:
  5591. !         CC_STATUS_INIT;
  5592. !       }
  5593. !       else
  5594.       {
  5595. !       CC_STATUS_INIT;
  5596. !     }
  5597. !     }
  5598. !   else if (GET_CODE (exp) == PARALLEL
  5599. !        && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
  5600. !     {
  5601. !       if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
  5602. !     return;
  5603. !       if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
  5604. !     {
  5605. !       CC_STATUS_INIT;
  5606. !       if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
  5607. !         cc_status.flags |= CC_IN_80387;
  5608.         else
  5609. !         cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
  5610. !       return;
  5611.       }
  5612. !       CC_STATUS_INIT;
  5613. !     }
  5614. !   else
  5615. !     {
  5616. !       CC_STATUS_INIT;
  5617. !     }
  5618. ! }
  5619. ! /* Split one or more DImode RTL references into pairs of SImode
  5620. !    references.  The RTL can be REG, offsettable MEM, integer constant, or
  5621. !    CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
  5622. !    split and "num" is its length.  lo_half and hi_half are output arrays
  5623. !    that parallel "operands". */
  5624.   
  5625. ! void
  5626. ! split_di (operands, num, lo_half, hi_half)
  5627. !      rtx operands[];
  5628. !      int num;
  5629. !      rtx lo_half[], hi_half[];
  5630. ! {
  5631. !   while (num--)
  5632. !     {
  5633. !       if (GET_CODE (operands[num]) == REG)
  5634.       {
  5635. !       lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
  5636. !       hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
  5637.       }
  5638. !       else if (CONSTANT_P (operands[num]))
  5639.       {
  5640. !       split_double (operands[num], &lo_half[num], &hi_half[num]);
  5641.       }
  5642. !       else if (offsettable_memref_p (operands[num]))
  5643. !     {
  5644. !       lo_half[num] = operands[num];
  5645. !       hi_half[num] = adj_offsettable_operand (operands[num], 4);
  5646. !     }
  5647. !       else
  5648. !     abort();
  5649. !     }
  5650. ! }
  5651. ! /* Return 1 if this is a valid binary operation on a 387.
  5652. !    OP is the expression matched, and MODE is its mode. */
  5653. ! int
  5654. ! binary_387_op (op, mode)
  5655. !     register rtx op;
  5656. !     enum machine_mode mode;
  5657. ! {
  5658. !   if (mode != VOIDmode && mode != GET_MODE (op))
  5659. !     return 0;
  5660.   
  5661. +   switch (GET_CODE (op))
  5662. +     {
  5663. +     case PLUS:
  5664.       case MINUS:
  5665. !     case MULT:
  5666. !     case DIV:
  5667. !       return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
  5668.   
  5669.       default:
  5670. !       return 0;
  5671.       }
  5672.   }
  5673.   
  5674. ! /* Return 1 if this is a valid conversion operation on a 387.
  5675. !    OP is the expression matched, and MODE is its mode. */
  5676. ! int
  5677. ! convert_387_op (op, mode)
  5678. !     register rtx op;
  5679. !     enum machine_mode mode;
  5680.   {
  5681. !   if (mode != VOIDmode && mode != GET_MODE (op))
  5682. !     return 0;
  5683. !   switch (GET_CODE (op))
  5684.       {
  5685. !     case FLOAT:
  5686. !       return GET_MODE (XEXP (op, 0)) == SImode;
  5687.   
  5688. !     case FLOAT_EXTEND:
  5689. !       return ((mode == DFmode && GET_MODE (XEXP (op, 0)) == SFmode)
  5690. !           || (mode == XFmode && GET_MODE (XEXP (op, 0)) == DFmode)
  5691. !           || (mode == XFmode && GET_MODE (XEXP (op, 0)) == SFmode));
  5692.   
  5693. !     default:
  5694. !       return 0;
  5695. !     }
  5696. ! }
  5697.   
  5698. ! /* Return 1 if this is a valid shift or rotate operation on a 386.
  5699. !    OP is the expression matched, and MODE is its mode. */
  5700.   
  5701. ! int
  5702. ! shift_op (op, mode)
  5703. !     register rtx op;
  5704. !     enum machine_mode mode;
  5705. ! {
  5706. !   rtx operand = XEXP (op, 0);
  5707.   
  5708. !   if (mode != VOIDmode && mode != GET_MODE (op))
  5709. !     return 0;
  5710.   
  5711. !   if (GET_MODE (operand) != GET_MODE (op)
  5712. !       || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
  5713. !     return 0;
  5714.   
  5715. !   return (GET_CODE (op) == ASHIFT
  5716. !       || GET_CODE (op) == ASHIFTRT
  5717. !       || GET_CODE (op) == LSHIFTRT
  5718. !       || GET_CODE (op) == ROTATE
  5719. !       || GET_CODE (op) == ROTATERT);
  5720. ! }
  5721.   
  5722. ! /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
  5723. !    MODE is not used.  */
  5724.   
  5725. ! int
  5726. ! VOIDmode_compare_op (op, mode)
  5727. !     register rtx op;
  5728. !     enum machine_mode mode;
  5729. ! {
  5730. !   return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
  5731. ! }
  5732. ! /* Output code to perform a 387 binary operation in INSN, one of PLUS,
  5733. !    MINUS, MULT or DIV.  OPERANDS are the insn operands, where operands[3]
  5734. !    is the expression of the binary operation.  The output may either be
  5735. !    emitted here, or returned to the caller, like all output_* functions.
  5736.   
  5737. !    There is no guarantee that the operands are the same mode, as they
  5738. !    might be within FLOAT or FLOAT_EXTEND expressions. */
  5739.   
  5740. ! char *
  5741. ! output_387_binary_op (insn, operands)
  5742. !      rtx insn;
  5743. !      rtx *operands;
  5744. ! {
  5745. !   rtx temp;
  5746. !   char *base_op;
  5747. !   static char buf[100];
  5748.   
  5749. !   switch (GET_CODE (operands[3]))
  5750. !     {
  5751. !     case PLUS:
  5752. !       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
  5753. !       || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
  5754. !     base_op = "fiadd";
  5755. !       else
  5756. !     base_op = "fadd";
  5757. !       break;
  5758.   
  5759. !     case MINUS:
  5760. !       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
  5761. !       || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
  5762. !     base_op = "fisub";
  5763. !       else
  5764. !     base_op = "fsub";
  5765. !       break;
  5766.   
  5767. !     case MULT:
  5768. !       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
  5769. !       || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
  5770. !     base_op = "fimul";
  5771. !       else
  5772. !     base_op = "fmul";
  5773. !       break;
  5774.   
  5775. !     case DIV:
  5776. !       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
  5777. !       || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
  5778. !     base_op = "fidiv";
  5779. !       else
  5780. !     base_op = "fdiv";
  5781. !       break;
  5782.   
  5783. !     default:
  5784. !       abort ();
  5785. !     }
  5786.   
  5787. !   strcpy (buf, base_op);
  5788.   
  5789. !   switch (GET_CODE (operands[3]))
  5790.       {
  5791. !     case MULT:
  5792. !     case PLUS:
  5793. !       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
  5794.       {
  5795. !       temp = operands[2];
  5796. !       operands[2] = operands[1];
  5797. !       operands[1] = temp;
  5798.       }
  5799.   
  5800. !       if (GET_CODE (operands[2]) == MEM)
  5801. !     return strcat (buf, AS1 (%z2,%2));
  5802.   
  5803. !       if (NON_STACK_REG_P (operands[1]))
  5804.       {
  5805. !       output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
  5806. !       RET;
  5807.       }
  5808. !       else if (NON_STACK_REG_P (operands[2]))
  5809.       {
  5810. !       output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
  5811. !       RET;
  5812.       }
  5813. !       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
  5814. !     return strcat (buf, AS2 (p,%2,%0));
  5815. !       if (STACK_TOP_P (operands[0]))
  5816. !     return strcat (buf, AS2 (,%y2,%0));
  5817. !       else
  5818. !     return strcat (buf, AS2 (,%2,%0));
  5819. !     case MINUS:
  5820. !     case DIV:
  5821. !       if (GET_CODE (operands[1]) == MEM)
  5822. !     return strcat (buf, AS1 (r%z1,%1));
  5823. !       if (GET_CODE (operands[2]) == MEM)
  5824. !     return strcat (buf, AS1 (%z2,%2));
  5825. !       if (NON_STACK_REG_P (operands[1]))
  5826.       {
  5827. !       output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
  5828. !       RET;
  5829.       }
  5830. !       else if (NON_STACK_REG_P (operands[2]))
  5831.       {
  5832. !       output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
  5833. !       RET;
  5834.       }
  5835. !       if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
  5836. !     abort ();
  5837. !       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
  5838. !     return strcat (buf, AS2 (rp,%2,%0));
  5839. !       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
  5840. !     return strcat (buf, AS2 (p,%1,%0));
  5841. !       if (STACK_TOP_P (operands[0]))
  5842.       {
  5843. !       if (STACK_TOP_P (operands[1]))
  5844. !         return strcat (buf, AS2 (,%y2,%0));
  5845. !       else
  5846. !         return strcat (buf, AS2 (r,%y1,%0));
  5847.       }
  5848. +       else if (STACK_TOP_P (operands[1]))
  5849. +     return strcat (buf, AS2 (,%1,%0));
  5850. +       else
  5851. +     return strcat (buf, AS2 (r,%2,%0));
  5852.   
  5853. !     default:
  5854. !       abort ();
  5855. !     }
  5856. ! }
  5857. ! /* Output code for INSN to convert a float to a signed int.  OPERANDS
  5858. !    are the insn operands.  The output may be SFmode or DFmode and the
  5859. !    input operand may be SImode or DImode.  As a special case, make sure
  5860. !    that the 387 stack top dies if the output mode is DImode, because the
  5861. !    hardware requires this.  */
  5862.   
  5863. ! char *
  5864. ! output_fix_trunc (insn, operands)
  5865. !      rtx insn;
  5866. !      rtx *operands;
  5867. ! {
  5868. !   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  5869. !   rtx xops[2];
  5870.   
  5871. !   if (! STACK_TOP_P (operands[1]) ||
  5872. !       (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
  5873. !     abort ();
  5874.   
  5875. !   xops[0] = GEN_INT (12);
  5876. !   xops[1] = operands[4];
  5877.   
  5878. !   output_asm_insn (AS1 (fnstc%W2,%2), operands);
  5879. !   output_asm_insn (AS2 (mov%L2,%2,%4), operands);
  5880. !   output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
  5881. !   output_asm_insn (AS2 (mov%L4,%4,%3), operands);
  5882. !   output_asm_insn (AS1 (fldc%W3,%3), operands);
  5883.   
  5884. !   if (NON_STACK_REG_P (operands[0]))
  5885. !     output_to_reg (operands[0], stack_top_dies);
  5886. !   else if (GET_CODE (operands[0]) == MEM)
  5887. !     {
  5888. !       if (stack_top_dies)
  5889. !     output_asm_insn (AS1 (fistp%z0,%0), operands);
  5890. !       else
  5891. !     output_asm_insn (AS1 (fist%z0,%0), operands);
  5892. !     }
  5893. !   else
  5894. !     abort ();
  5895.   
  5896. !   return AS1 (fldc%W2,%2);
  5897. ! }
  5898. ! /* Output code for INSN to compare OPERANDS.  The two operands might
  5899. !    not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
  5900. !    expression.  If the compare is in mode CCFPEQmode, use an opcode that
  5901. !    will not fault if a qNaN is present. */
  5902.   
  5903. ! char *
  5904. ! output_float_compare (insn, operands)
  5905. !      rtx insn;
  5906. !      rtx *operands;
  5907. ! {
  5908. !   int stack_top_dies;
  5909. !   rtx body = XVECEXP (PATTERN (insn), 0, 0);
  5910. !   int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
  5911.   
  5912. !   /* intel1 */
  5913. !   rtx tmp;
  5914. !   if (! STACK_TOP_P (operands[0]))
  5915. !     {
  5916. !       tmp = operands[0];
  5917. !       operands[0] = operands[1];
  5918. !       operands[1] = tmp;
  5919. !       cc_status.flags |= CC_REVERSED;
  5920. !     }
  5921. !     
  5922. !   if (! STACK_TOP_P (operands[0]))
  5923. !     abort ();
  5924.   
  5925. !   stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  5926.   
  5927. !   if (STACK_REG_P (operands[1])
  5928. !       && stack_top_dies
  5929. !       && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
  5930. !       && REGNO (operands[1]) != FIRST_STACK_REG)
  5931. !     {
  5932. !       /* If both the top of the 387 stack dies, and the other operand
  5933. !      is also a stack register that dies, then this must be a
  5934. !      `fcompp' float compare */
  5935. !       if (unordered_compare)
  5936. !     output_asm_insn ("fucompp", operands);
  5937.         else
  5938. !     output_asm_insn ("fcompp", operands);
  5939.       }
  5940. +   else
  5941. +     {
  5942. +       static char buf[100];
  5943. +       /* Decide if this is the integer or float compare opcode, or the
  5944. +      unordered float compare. */
  5945. +       if (unordered_compare)
  5946. +     strcpy (buf, "fucom");
  5947. +       else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
  5948. +     strcpy (buf, "fcom");
  5949. +       else
  5950. +     strcpy (buf, "ficom");
  5951. +       /* Modify the opcode if the 387 stack is to be popped. */
  5952. +       if (stack_top_dies)
  5953. +     strcat (buf, "p");
  5954. +       if (NON_STACK_REG_P (operands[1]))
  5955. +     output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
  5956. +       else
  5957. +         output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
  5958. +     }
  5959. +   /* Now retrieve the condition code. */
  5960. +   return output_fp_cc0_set (insn);
  5961.   }
  5962.   
  5963. ! /* Output opcodes to transfer the results of FP compare or test INSN
  5964. !    from the FPU to the CPU flags.  If TARGET_IEEE_FP, ensure that if the
  5965. !    result of the compare or test is unordered, no comparison operator
  5966. !    succeeds except NE.  Return an output template, if any.  */
  5967.   
  5968. ! char *
  5969. ! output_fp_cc0_set (insn)
  5970. !      rtx insn;
  5971. ! {
  5972. !   rtx xops[3];
  5973. !   rtx unordered_label;
  5974. !   rtx next;
  5975. !   enum rtx_code code;
  5976.   
  5977. !   xops[0] = gen_rtx (REG, HImode, 0);
  5978. !   output_asm_insn (AS1 (fnsts%W0,%0), xops);
  5979.   
  5980. !   if (! TARGET_IEEE_FP)
  5981.       {
  5982. !       /* intel1 */
  5983. !       if (!(cc_status.flags & CC_REVERSED))
  5984. !         {
  5985. !           next = next_cc0_user (insn);
  5986. !         
  5987. !           if (GET_CODE (next) == JUMP_INSN
  5988. !               && GET_CODE (PATTERN (next)) == SET
  5989. !               && SET_DEST (PATTERN (next)) == pc_rtx
  5990. !               && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
  5991. !             {
  5992. !               code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
  5993. !             }
  5994. !           else if (GET_CODE (PATTERN (next)) == SET)
  5995. !             {
  5996. !               code = GET_CODE (SET_SRC (PATTERN (next)));
  5997. !             }
  5998. !           else
  5999. !             {
  6000. !               return "sahf";
  6001. !             }
  6002. !           if (code == GT || code == LT || code == EQ || code == NE
  6003. !               || code == LE || code == GE)
  6004. !             { /* We will test eax directly */
  6005. !               cc_status.flags |= CC_TEST_AX;
  6006. !               RET;
  6007. !             }
  6008. !         }
  6009. !       return "sahf";
  6010. !     }
  6011.   
  6012. !   next = next_cc0_user (insn);
  6013. !   if (next == NULL_RTX)
  6014. !     abort ();
  6015.   
  6016. !   if (GET_CODE (next) == JUMP_INSN
  6017. !       && GET_CODE (PATTERN (next)) == SET
  6018. !       && SET_DEST (PATTERN (next)) == pc_rtx
  6019. !       && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
  6020. !     {
  6021. !       code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
  6022.       }
  6023. !   else if (GET_CODE (PATTERN (next)) == SET)
  6024.       {
  6025. !       code = GET_CODE (SET_SRC (PATTERN (next)));
  6026.       }
  6027.     else
  6028. +     abort ();
  6029. +   xops[0] = gen_rtx (REG, QImode, 0);
  6030. +   switch (code)
  6031.       {
  6032. !     case GT:
  6033. !       xops[1] = GEN_INT (0x45);
  6034. !       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
  6035. !       /* je label */
  6036. !       break;
  6037. !     case LT:
  6038. !       xops[1] = GEN_INT (0x45);
  6039. !       xops[2] = GEN_INT (0x01);
  6040. !       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
  6041. !       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
  6042. !       /* je label */
  6043. !       break;
  6044. !     case GE:
  6045. !       xops[1] = GEN_INT (0x05);
  6046. !       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
  6047. !       /* je label */
  6048. !       break;
  6049. !     case LE:
  6050. !       xops[1] = GEN_INT (0x45);
  6051. !       xops[2] = GEN_INT (0x40);
  6052. !       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
  6053. !       output_asm_insn (AS1 (dec%B0,%h0), xops);
  6054. !       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
  6055. !       /* jb label */
  6056. !       break;
  6057. !     case EQ:
  6058. !       xops[1] = GEN_INT (0x45);
  6059. !       xops[2] = GEN_INT (0x40);
  6060. !       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
  6061. !       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
  6062. !       /* je label */
  6063. !       break;
  6064. !     case NE:
  6065. !       xops[1] = GEN_INT (0x44);
  6066. !       xops[2] = GEN_INT (0x40);
  6067. !       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
  6068. !       output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
  6069. !       /* jne label */
  6070. !       break;
  6071. !     case GTU:
  6072. !     case LTU:
  6073. !     case GEU:
  6074. !     case LEU:
  6075. !     default:
  6076. !       abort ();
  6077.       }
  6078. +   RET;
  6079. + }
  6080. + #define MAX_386_STACK_LOCALS 2
  6081. + static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
  6082. + /* Define the structure for the machine field in struct function.  */
  6083. + struct machine_function
  6084. + {
  6085. +   rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
  6086. + };
  6087. + /* Functions to save and restore i386_stack_locals.
  6088. +    These will be called, via pointer variables,
  6089. +    from push_function_context and pop_function_context.  */
  6090. + void
  6091. + save_386_machine_status (p)
  6092. +      struct function *p;
  6093. + {
  6094. +   p->machine = (struct machine_function *) xmalloc (sizeof i386_stack_locals);
  6095. +   bcopy (i386_stack_locals, p->machine->i386_stack_locals,
  6096. +      sizeof i386_stack_locals);
  6097.   }
  6098.   
  6099.   void
  6100. ! restore_386_machine_status (p)
  6101. !      struct function *p;
  6102.   {
  6103. !   bcopy (p->machine->i386_stack_locals, i386_stack_locals,
  6104. !      sizeof i386_stack_locals);
  6105. !   free (p->machine);
  6106.   }
  6107.   
  6108. ! /* Clear stack slot assignments remembered from previous functions.
  6109. !    This is called from INIT_EXPANDERS once before RTL is emitted for each
  6110. !    function.  */
  6111. ! void
  6112. ! clear_386_stack_locals ()
  6113.   {
  6114. !   enum machine_mode mode;
  6115. !   int n;
  6116.   
  6117. !   for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
  6118. !        mode = (enum machine_mode) ((int) mode + 1))
  6119. !     for (n = 0; n < MAX_386_STACK_LOCALS; n++)
  6120. !       i386_stack_locals[(int) mode][n] = NULL_RTX;
  6121.   
  6122. !   /* Arrange to save and restore i386_stack_locals around nested functions.  */
  6123. !   save_machine_status = save_386_machine_status;
  6124. !   restore_machine_status = restore_386_machine_status;
  6125.   }
  6126.   
  6127. ! /* Return a MEM corresponding to a stack slot with mode MODE.
  6128. !    Allocate a new slot if necessary.
  6129.   
  6130. !    The RTL for a function can have several slots available: N is
  6131. !    which slot to use.  */
  6132. ! rtx
  6133. ! assign_386_stack_local (mode, n)
  6134. !      enum machine_mode mode;
  6135. !      int n;
  6136.   {
  6137. !   if (n < 0 || n >= MAX_386_STACK_LOCALS)
  6138. !     abort ();
  6139.   
  6140. !   if (i386_stack_locals[(int) mode][n] == NULL_RTX)
  6141. !   {
  6142. !     i386_stack_locals[(int) mode][n]
  6143. !       = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
  6144. !   }
  6145. !   return i386_stack_locals[(int) mode][n];
  6146. ! }
  6147.   
  6148.   
  6149. ! /* all functions after here added by intel1 */
  6150. ! /* intel1 */
  6151. ! int is_mul(op,mode)
  6152. !     register rtx op;
  6153. !     enum machine_mode mode;
  6154. ! {
  6155. !   return(GET_CODE(op)==MULT);
  6156.   }
  6157.   
  6158. ! /* intel1 */
  6159. ! int is_div(op,mode)
  6160.       register rtx op;
  6161.       enum machine_mode mode;
  6162.   {
  6163. !   return(GET_CODE(op)==DIV);
  6164.   }
  6165.   
  6166. ! /* Create a new copy of an rtx.
  6167. !    Recursively copies the operands of the rtx,
  6168. !    except for those few rtx codes that are sharable.
  6169. !    Doesn't share CONST  */
  6170.   
  6171. ! rtx
  6172. ! copy_all_rtx (orig)
  6173. !      register rtx orig;
  6174.   {
  6175. !   register rtx copy;
  6176. !   register int i, j;
  6177. !   register RTX_CODE code;
  6178. !   register char *format_ptr;
  6179.   
  6180. !   code = GET_CODE (orig);
  6181. !   switch (code)
  6182.       {
  6183. !     case REG:
  6184. !     case QUEUED:
  6185. !     case CONST_INT:
  6186. !     case CONST_DOUBLE:
  6187. !     case SYMBOL_REF:
  6188. !     case CODE_LABEL:
  6189. !     case PC:
  6190. !     case CC0:
  6191. !     case SCRATCH:
  6192. !       /* SCRATCH must be shared because they represent distinct values. */
  6193. !       return orig;
  6194.   
  6195. ! #if 0
  6196. !     case CONST:
  6197. !       /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
  6198. !      a LABEL_REF, it isn't sharable.  */
  6199. !       if (GET_CODE (XEXP (orig, 0)) == PLUS
  6200. !       && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
  6201. !       && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
  6202. !     return orig;
  6203.         break;
  6204. + #endif
  6205. +       /* A MEM with a constant address is not sharable.  The problem is that
  6206. +      the constant address may need to be reloaded.  If the mem is shared,
  6207. +      then reloading one copy of this mem will cause all copies to appear
  6208. +      to have been reloaded.  */
  6209. +     }
  6210. +   copy = rtx_alloc (code);
  6211. +   PUT_MODE (copy, GET_MODE (orig));
  6212. +   copy->in_struct = orig->in_struct;
  6213. +   copy->volatil = orig->volatil;
  6214. +   copy->unchanging = orig->unchanging;
  6215. +   copy->integrated = orig->integrated;
  6216. +   /* intel1 */
  6217. +   copy->is_spill_rtx = orig->is_spill_rtx;
  6218. +   
  6219. +   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
  6220. +   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
  6221. +     {
  6222. +       switch (*format_ptr++)
  6223. +     {
  6224. +     case 'e':
  6225. +       XEXP (copy, i) = XEXP (orig, i);
  6226. +       if (XEXP (orig, i) != NULL)
  6227. +         XEXP (copy, i) = copy_rtx (XEXP (orig, i));
  6228. +       break;
  6229.   
  6230. !     case '0':
  6231. !     case 'u':
  6232. !       XEXP (copy, i) = XEXP (orig, i);
  6233. !       break;
  6234.   
  6235. !     case 'E':
  6236. !     case 'V':
  6237. !       XVEC (copy, i) = XVEC (orig, i);
  6238. !       if (XVEC (orig, i) != NULL)
  6239. !         {
  6240. !           XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
  6241. !           for (j = 0; j < XVECLEN (copy, i); j++)
  6242. !         XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
  6243. !         }
  6244. !       break;
  6245.   
  6246. !     case 'w':
  6247. !       XWINT (copy, i) = XWINT (orig, i);
  6248. !       break;
  6249. !     case 'i':
  6250. !       XINT (copy, i) = XINT (orig, i);
  6251. !       break;
  6252. !     case 's':
  6253. !     case 'S':
  6254. !       XSTR (copy, i) = XSTR (orig, i);
  6255. !       break;
  6256. !     default:
  6257. !       abort ();
  6258. !     }
  6259. !     }
  6260. !   return copy;
  6261. ! }
  6262. ! /* try to rewrite a memory address to make it valid */
  6263. ! void 
  6264. ! rewrite_address (mem_rtx)
  6265. !      rtx mem_rtx;
  6266. ! {
  6267. !   rtx index_rtx, base_rtx, offset_rtx, scale_rtx, ret_rtx;
  6268. !   int scale = 1;
  6269. !   int offset_adjust = 0;
  6270. !   int was_only_offset = 0;
  6271. !   rtx mem_addr = XEXP (mem_rtx, 0);
  6272. !   char *storage = (char *) oballoc (0);
  6273. !   int in_struct = 0;
  6274. !   int is_spill_rtx = 0;
  6275. !   in_struct = MEM_IN_STRUCT_P (mem_rtx);
  6276. !   is_spill_rtx = RTX_IS_SPILL_P (mem_rtx);
  6277. !   if (GET_CODE (mem_addr) == PLUS &&
  6278. !       GET_CODE (XEXP (mem_addr, 1)) == PLUS &&
  6279. !       GET_CODE (XEXP (XEXP (mem_addr, 1), 0)) == REG)
  6280. !     {                /* this part is utilized by the combiner */
  6281. !       ret_rtx =
  6282. !     gen_rtx (PLUS, GET_MODE (mem_addr),
  6283. !          gen_rtx (PLUS, GET_MODE (XEXP (mem_addr, 1)),
  6284. !               XEXP (mem_addr, 0),
  6285. !               XEXP (XEXP (mem_addr, 1), 0)),
  6286. !          XEXP (XEXP (mem_addr, 1), 1));
  6287. !       if (memory_address_p (GET_MODE (mem_rtx), ret_rtx))
  6288. !     {
  6289. !       XEXP (mem_rtx, 0) = ret_rtx;
  6290. !       RTX_IS_SPILL_P (ret_rtx) = is_spill_rtx;
  6291. !       return;
  6292. !     }
  6293. !       obfree (storage);
  6294. !     }
  6295. !   /* this part is utilized by loop.c */
  6296. !   /* If the address contains PLUS (reg,const) and this pattern is invalid
  6297. !      in this case - try to rewrite the address to make it valid  intel1
  6298. !   */
  6299. !   storage = (char *) oballoc (0);
  6300. !   index_rtx = base_rtx = offset_rtx = NULL;
  6301. !   /* find the base index and offset elements of the memory address */
  6302. !   if (GET_CODE (mem_addr) == PLUS)
  6303. !     {
  6304. !       if (GET_CODE (XEXP (mem_addr, 0)) == REG)
  6305. !     {
  6306. !       if (GET_CODE (XEXP (mem_addr, 1)) == REG)
  6307. !         {
  6308. !           base_rtx = XEXP (mem_addr, 1);
  6309. !           index_rtx = XEXP (mem_addr, 0);
  6310. !         }
  6311. !       else
  6312. !         {
  6313. !           base_rtx = XEXP (mem_addr, 0);
  6314. !           offset_rtx = XEXP (mem_addr, 1);
  6315. !         }
  6316. !     }
  6317. !       else if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
  6318. !     {
  6319. !       index_rtx = XEXP (mem_addr, 0);
  6320. !       if (GET_CODE (XEXP (mem_addr, 1)) == REG)
  6321. !         {
  6322. !           base_rtx = XEXP (mem_addr, 1);
  6323. !         }
  6324. !       else
  6325. !         {
  6326. !           offset_rtx = XEXP (mem_addr, 1);
  6327. !         }
  6328. !     }
  6329. !       else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
  6330. !     {
  6331. !       /* intel1 */
  6332. !       if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == PLUS &&
  6333. !           GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == MULT &&
  6334. !           GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 0)) == REG &&
  6335. !           GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 1)) == CONST_INT &&
  6336. !           GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1)) == CONST_INT &&
  6337. !           GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG &&
  6338. !           GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF)
  6339. !         {
  6340. !           index_rtx = XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
  6341. !           offset_rtx = XEXP (mem_addr, 1);
  6342. !           base_rtx = XEXP (XEXP (mem_addr, 0), 1);
  6343. !           offset_adjust = INTVAL (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1));
  6344. !         }
  6345. !       else
  6346. !         {
  6347. !           offset_rtx = XEXP (mem_addr, 1);
  6348. !           index_rtx = XEXP (XEXP (mem_addr, 0), 0);
  6349. !           base_rtx = XEXP (XEXP (mem_addr, 0), 1);
  6350. !         }
  6351. !     }
  6352. !       else if (GET_CODE (XEXP (mem_addr, 0)) == CONST_INT)
  6353. !     {
  6354. !       was_only_offset = 1;
  6355. !       index_rtx = NULL;
  6356. !       base_rtx = NULL;
  6357. !       offset_rtx = XEXP (mem_addr, 1);
  6358. !       offset_adjust = INTVAL (XEXP (mem_addr, 0));
  6359. !       if (offset_adjust == 0)
  6360. !         {
  6361. !           XEXP (mem_rtx, 0) = offset_rtx;
  6362. !           RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
  6363. !           return;
  6364. !         }
  6365. !     }
  6366. !       else
  6367. !     {
  6368. !       obfree (storage);
  6369. !       return;
  6370. !     }
  6371. !     }
  6372. !   else if (GET_CODE (mem_addr) == MULT)
  6373. !     {
  6374. !       index_rtx = mem_addr;
  6375. !     }
  6376. !   else
  6377. !     {
  6378. !       obfree (storage);
  6379. !       return;
  6380. !     }
  6381. !   if (index_rtx && GET_CODE (index_rtx) == MULT)
  6382. !     {
  6383. !       if (GET_CODE (XEXP (index_rtx, 1)) != CONST_INT)
  6384. !     {
  6385. !       obfree (storage);
  6386. !       return;
  6387. !     }
  6388. !       scale_rtx = XEXP (index_rtx, 1);
  6389. !       scale = INTVAL (scale_rtx);
  6390. !       index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
  6391. !     }
  6392. !   /* now find which of the elements are invalid and try to fix them */
  6393. !   if (index_rtx && GET_CODE (index_rtx) == CONST_INT && base_rtx == NULL)
  6394. !     {
  6395. !       offset_adjust = INTVAL (index_rtx) * scale;
  6396. !       if (offset_rtx && GET_CODE (offset_rtx) == CONST &&
  6397. !       GET_CODE (XEXP (offset_rtx, 0)) == PLUS)
  6398. !     {
  6399. !       if (GET_CODE (XEXP (XEXP (offset_rtx, 0), 0)) == SYMBOL_REF &&
  6400. !           GET_CODE (XEXP (XEXP (offset_rtx, 0), 1)) == CONST_INT)
  6401. !         {
  6402. !           offset_rtx = copy_all_rtx (offset_rtx);
  6403. !           XEXP (XEXP (offset_rtx, 0), 1) =
  6404. !         gen_rtx (CONST_INT, 0, INTVAL (XEXP (XEXP (offset_rtx, 0), 1)) + offset_adjust);
  6405. !           if (!CONSTANT_P (offset_rtx))
  6406. !         {
  6407. !           obfree (storage);
  6408. !           return;
  6409. !         }
  6410. !         }
  6411. !     }
  6412. !       else if (offset_rtx && GET_CODE (offset_rtx) == SYMBOL_REF)
  6413. !     {
  6414. !       offset_rtx =
  6415. !         gen_rtx (CONST, GET_MODE (offset_rtx),
  6416. !              gen_rtx (PLUS, GET_MODE (offset_rtx),
  6417. !                   offset_rtx,
  6418. !                   gen_rtx (CONST_INT, 0, offset_adjust)));
  6419. !       if (!CONSTANT_P (offset_rtx))
  6420. !         {
  6421. !           obfree (storage);
  6422. !           return;
  6423. !         }
  6424. !     }
  6425. !       else if (offset_rtx && GET_CODE (offset_rtx) == CONST_INT)
  6426. !     {
  6427. !       offset_rtx = gen_rtx (CONST_INT, 0, INTVAL (offset_rtx) + offset_adjust);
  6428. !     }
  6429. !       else if (!offset_rtx)
  6430. !     {
  6431. !       offset_rtx = gen_rtx (CONST_INT, 0, 0);
  6432. !     }
  6433. !       RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
  6434. !       XEXP (mem_rtx, 0) = offset_rtx;
  6435. !       return;
  6436.       }
  6437. !   if (base_rtx && GET_CODE (base_rtx) == PLUS &&
  6438. !       GET_CODE (XEXP (base_rtx, 0)) == REG &&
  6439. !       GET_CODE (XEXP (base_rtx, 1)) == CONST_INT)
  6440.       {
  6441. !       offset_adjust += INTVAL (XEXP (base_rtx, 1));
  6442. !       base_rtx = copy_all_rtx (XEXP (base_rtx, 0));
  6443. !     }
  6444. !   else if (base_rtx && GET_CODE (base_rtx) == CONST_INT)
  6445. !     {
  6446. !       offset_adjust += INTVAL (base_rtx);
  6447. !       base_rtx = NULL;
  6448. !     }
  6449. !   if (index_rtx && GET_CODE (index_rtx) == PLUS &&
  6450. !       GET_CODE (XEXP (index_rtx, 0)) == REG &&
  6451. !       GET_CODE (XEXP (index_rtx, 1)) == CONST_INT)
  6452. !     {
  6453. !       offset_adjust += INTVAL (XEXP (index_rtx, 1)) * scale;
  6454. !       index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
  6455. !     }
  6456. !   if (index_rtx)
  6457. !     {
  6458. !       if (!LEGITIMATE_INDEX_P (index_rtx)
  6459. !       && !(index_rtx == stack_pointer_rtx && scale == 1 && base_rtx == NULL))
  6460.       {
  6461. !       obfree (storage);
  6462. !       return;
  6463.       }
  6464. !     }
  6465. !   if (base_rtx)
  6466. !     {
  6467. !       if (!LEGITIMATE_INDEX_P (base_rtx) && GET_CODE (base_rtx) != REG)
  6468.       {
  6469. !       obfree (storage);
  6470. !       return;
  6471.       }
  6472. !     }
  6473. !   if (offset_adjust != 0)
  6474. !     {
  6475. !       if (offset_rtx)
  6476.       {
  6477. !       if (GET_CODE (offset_rtx) == CONST &&
  6478. !           GET_CODE (XEXP (offset_rtx, 0)) == PLUS)
  6479. !         {
  6480. !           if (GET_CODE (XEXP (XEXP (offset_rtx, 0), 0)) == SYMBOL_REF &&
  6481. !           GET_CODE (XEXP (XEXP (offset_rtx, 0), 1)) == CONST_INT)
  6482. !         {
  6483. !           offset_rtx = copy_all_rtx (offset_rtx);
  6484. !           XEXP (XEXP (offset_rtx, 0), 1) =
  6485. !             gen_rtx (CONST_INT, 0, INTVAL (XEXP (XEXP (offset_rtx, 0), 1)) + offset_adjust);
  6486. !           if (!CONSTANT_P (offset_rtx))
  6487. !             {
  6488. !               obfree (storage);
  6489. !               return;
  6490. !             }
  6491. !         }
  6492. !         }
  6493. !       else if (GET_CODE (offset_rtx) == SYMBOL_REF)
  6494. !         {
  6495. !           offset_rtx =
  6496. !         gen_rtx (CONST, GET_MODE (offset_rtx),
  6497. !              gen_rtx (PLUS, GET_MODE (offset_rtx),
  6498. !                   offset_rtx,
  6499. !                   gen_rtx (CONST_INT, 0, offset_adjust)));
  6500. !           if (!CONSTANT_P (offset_rtx))
  6501. !         {
  6502. !           obfree (storage);
  6503. !           return;
  6504. !         }
  6505. !         }
  6506. !       else if (GET_CODE (offset_rtx) == CONST_INT)
  6507. !         {
  6508. !           offset_rtx = gen_rtx (CONST_INT, 0, INTVAL (offset_rtx) + offset_adjust);
  6509. !         }
  6510. !       else
  6511. !         {
  6512. !           obfree (storage);
  6513. !           return;
  6514. !         }
  6515.       }
  6516.         else
  6517.       {
  6518. !       offset_rtx = gen_rtx (CONST_INT, 0, offset_adjust);
  6519.       }
  6520. !       if (index_rtx)
  6521.       {
  6522. !       if (base_rtx)
  6523. !         {
  6524. !           if (scale != 1)
  6525. !         {
  6526. !           if (GET_CODE (offset_rtx) == CONST_INT &&
  6527. !               INTVAL (offset_rtx) == 0)
  6528. !             {
  6529. !               ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx),
  6530. !                  gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
  6531. !                       scale_rtx),
  6532. !                      base_rtx);
  6533. !             }
  6534. !           else
  6535. !             {
  6536. !               ret_rtx = gen_rtx (PLUS, GET_MODE (offset_rtx),
  6537. !                      gen_rtx (PLUS, GET_MODE (base_rtx),
  6538. !                  gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
  6539. !                       scale_rtx),
  6540. !                           base_rtx),
  6541. !                      offset_rtx);
  6542. !             }
  6543. !         }
  6544. !           else
  6545. !         {
  6546. !           if (GET_CODE (offset_rtx) == CONST_INT &&
  6547. !               INTVAL (offset_rtx) == 0)
  6548. !             {
  6549. !               ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx, base_rtx);
  6550. !             }
  6551. !           else
  6552. !             {
  6553. !               ret_rtx = gen_rtx (PLUS, GET_MODE (offset_rtx),
  6554. !                  gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx,
  6555. !                       base_rtx),
  6556. !                      offset_rtx);
  6557. !             }
  6558. !         }
  6559. !         }
  6560. !       else
  6561. !         {
  6562. !           if (scale != 1)
  6563. !         {
  6564. !           if (GET_CODE (offset_rtx) == CONST_INT &&
  6565. !               INTVAL (offset_rtx) == 0)
  6566. !             {
  6567. !               ret_rtx = gen_rtx (MULT, GET_MODE (index_rtx), index_rtx, scale_rtx);
  6568. !             }
  6569. !           else
  6570. !             {
  6571. !               ret_rtx =
  6572. !             gen_rtx (PLUS, GET_MODE (offset_rtx),
  6573. !                  gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
  6574. !                       scale_rtx),
  6575. !                  offset_rtx);
  6576. !             }
  6577. !         }
  6578. !           else
  6579. !         {
  6580. !           if (GET_CODE (offset_rtx) == CONST_INT &&
  6581. !               INTVAL (offset_rtx) == 0)
  6582. !             {
  6583. !               ret_rtx = index_rtx;
  6584. !             }
  6585. !           else
  6586. !             {
  6587. !               ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx, offset_rtx);
  6588. !             }
  6589. !         }
  6590. !         }
  6591.       }
  6592. !       else
  6593.       {
  6594. !       if (base_rtx)
  6595. !         {
  6596. !           if (GET_CODE (offset_rtx) == CONST_INT &&
  6597. !           INTVAL (offset_rtx) == 0)
  6598. !         {
  6599. !           ret_rtx = base_rtx;
  6600. !         }
  6601. !           else
  6602. !         {
  6603. !           ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx), base_rtx, offset_rtx);
  6604. !         }
  6605. !         }
  6606. !       else if (was_only_offset)
  6607. !         {
  6608. !           ret_rtx = offset_rtx;
  6609. !         }
  6610.         else
  6611. !         {
  6612. !           obfree (storage);
  6613. !           return;
  6614. !         }
  6615.       }
  6616. !       XEXP (mem_rtx, 0) = ret_rtx;
  6617. !       RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
  6618. !       return;
  6619. !     }
  6620. !   else
  6621. !     {
  6622. !       obfree (storage);
  6623. !       return;
  6624.       }
  6625.   }
  6626.   
  6627. ! /* return 1 if the first insn to set cc before insn also sets the register
  6628. !    reg_rtx - otherwise return 0
  6629. ! */
  6630. ! int
  6631. ! last_to_set_cc (reg_rtx, insn)
  6632. !      rtx reg_rtx, insn;
  6633.   {
  6634. !   rtx prev_insn = PREV_INSN (insn);
  6635.   
  6636. !   while (prev_insn)
  6637.       {
  6638. !       if (GET_CODE (prev_insn) == NOTE)
  6639. !     {
  6640. !       ;
  6641. !     }
  6642. !       else if (GET_CODE (prev_insn) == INSN)
  6643. !     {
  6644. !       if (GET_CODE (PATTERN (prev_insn)) != SET)
  6645. !         {
  6646. !           return (0);
  6647. !         }
  6648. !       if (rtx_equal_p (SET_DEST (PATTERN (prev_insn)), reg_rtx))
  6649. !         {
  6650. !           if (sets_condition_code (SET_SRC (PATTERN (prev_insn))))
  6651. !         {
  6652. !           return (1);
  6653. !         }
  6654. !           else
  6655. !         {
  6656. !           return (0);
  6657. !         }
  6658. !         }
  6659. !       else if (!doesnt_set_condition_code (SET_SRC (PATTERN (prev_insn))))
  6660. !         {
  6661. !           return (0);
  6662. !         }
  6663. !     }
  6664.         else
  6665. !     {
  6666. !       return (0);
  6667. !     }
  6668. !       prev_insn = PREV_INSN (prev_insn);
  6669.       }
  6670. !   return (0);
  6671.   }
  6672.   
  6673. ! int
  6674. ! doesnt_set_condition_code (pat)
  6675. !      rtx pat;
  6676.   {
  6677. !   switch (GET_CODE (pat))
  6678.       {
  6679. !     case MEM:
  6680. !     case REG:
  6681. !       return (1);
  6682.   
  6683. !     default:
  6684. !       return (0);
  6685.   
  6686. !     }
  6687.   }
  6688.   
  6689. ! int
  6690. ! sets_condition_code (pat)
  6691. !      rtx pat;
  6692.   {
  6693. !   switch (GET_CODE (pat))
  6694. !     {
  6695. !     case PLUS:
  6696. !     case MINUS:
  6697. !     case AND:
  6698. !     case IOR:
  6699. !     case XOR:
  6700. !     case NOT:
  6701. !     case NEG:
  6702. !     case MULT:
  6703. !     case DIV:
  6704. !     case MOD:
  6705. !     case UDIV:
  6706. !     case UMOD:
  6707. !       return (1);
  6708.   
  6709. !     default:
  6710. !       return (0);
  6711.   
  6712. !     }
  6713. ! }
  6714.   
  6715.   
  6716. ! /* intel1 */
  6717. ! int
  6718. ! str_immediate_operand (op, mode)
  6719. !      register rtx op;
  6720. !      enum machine_mode mode;
  6721. ! {
  6722. !   if (GET_CODE (op) == CONST_INT && INTVAL (op) <= 32 && INTVAL (op) >= 0)
  6723.       {
  6724. !       return (1);
  6725.       }
  6726. !   return (0);
  6727. ! }
  6728.   
  6729. ! /* intel1 */
  6730. ! void
  6731. ! override_options ()
  6732. ! {
  6733. !   register int i, start;
  6734. !   register int regno;
  6735. !   register enum machine_mode mode;
  6736. !   char *p;
  6737. ! #if 0
  6738. !   int blend = 0;
  6739. ! #endif
  6740.   
  6741. !   /* only one `-mcpu' allowed */
  6742. !   if (TARGET_X && (TARGET_X != TARGET_386) && (TARGET_X != TARGET_486) && (TARGET_X != TARGET_PENTIUM))
  6743. !     fatal ("multilple `-mcpu' definitions .\n");
  6744. !  /* if `-mcpu' use it, otherwise take default */
  6745. !  target_flags |= USE_CPU;
  6746. !   if (TARGET_PENTIUM)
  6747. !     x86_cpu = PROCESSOR_PENTIUM;
  6748. !   else if (TARGET_486)
  6749. !     x86_cpu = PROCESSOR_486;
  6750. !   else if (TARGET_386)
  6751. !     x86_cpu = PROCESSOR_386;
  6752. !   else /* no processor type ? */
  6753. !     fatal ("no processor type.\n");
  6754. !   
  6755. ! #if 0 /* what happens if we have few -mcpu's, I don't think it's needed */
  6756. !   /* Identify the processor type */
  6757. !   if (!(TARGET_PENTIUM) && !(TARGET_486) && !(TARGET_386))
  6758. !     {
  6759. !       x86_cpu = PROCESSOR_PENTIUM;
  6760. !       target_flags |= (TARGET_486_SWITCH);
  6761. !       blend = 1;
  6762. !     }
  6763. !   else
  6764.       {
  6765. !       x86_cpu = PROCESSOR_DEFAULT;
  6766. !       if (TARGET_PENTIUM)
  6767. !     {
  6768. !       x86_cpu = PROCESSOR_PENTIUM;
  6769. !     }
  6770. !       if (TARGET_486)
  6771. !     {
  6772. !       if (x86_cpu != PROCESSOR_DEFAULT)
  6773. !         {
  6774. !           error ("conflicting -mX86 : using blend");
  6775. !           blend = 1;
  6776. !           x86_cpu = PROCESSOR_PENTIUM;
  6777. !           target_flags &= ~(TARGET_386_SWITCH);
  6778. !           target_flags &= ~(TARGET_PENTIUM_SWITCH);
  6779. !         }
  6780. !       else
  6781. !         {
  6782. !           x86_cpu = PROCESSOR_486;
  6783. !         }
  6784. !     }
  6785. !       if (TARGET_386)
  6786. !     {
  6787. !       if (x86_cpu != PROCESSOR_DEFAULT)
  6788. !         {
  6789. !           error ("conflicting -mX86 : using blend");
  6790. !           blend = 1;
  6791. !           x86_cpu = PROCESSOR_486;
  6792. !           target_flags &= ~(TARGET_386_SWITCH);
  6793. !           target_flags &= ~(TARGET_PENTIUM_SWITCH);
  6794. !           target_flags |= (TARGET_486_SWITCH);
  6795. !         }
  6796. !       else
  6797. !         {
  6798. !           x86_cpu = PROCESSOR_386;
  6799. !         }
  6800. !     }
  6801.   
  6802.   
  6803. !     }
  6804. ! #endif
  6805. !   if (opt_level >= 4)
  6806. !     {
  6807. !       if (TARGET_486)
  6808. !         {
  6809. !       if (opt_level == 4
  6810. !           && !flag_no_interleave_stack_non_stack)
  6811. !         {
  6812. !           flag_interleave_stack_non_stack = 1;
  6813. !           flag_schedule_insns = 1;
  6814. !         }
  6815. !         }
  6816. ! #if 0
  6817. !       if(TARGET_BLEND)
  6818. !         {
  6819. !           if (!flag_no_risc)
  6820. !             flag_risc = 1;
  6821. !           if (!flag_no_risc_const)
  6822. !             flag_risc_const = 1;
  6823. !           if (!flag_no_recombine)
  6824. !             flag_recombine = 1;
  6825. !         }
  6826. ! #endif
  6827. !       if (TARGET_PENTIUM)
  6828. !         {
  6829. !           if (!flag_no_risc)
  6830. !             flag_risc = 1;
  6831. !           if (!flag_no_risc_const)
  6832. !             flag_risc_const = 1;
  6833. !           /*if (!flag_no_recombine)
  6834. !             flag_recombine = 1;*/
  6835. !       if (opt_level == 4
  6836. !           && !flag_no_schedule_stack_reg_insns)
  6837. !         {
  6838. !           flag_schedule_stack_reg_insns = 1;
  6839. !           flag_schedule_insns = 1;
  6840. !         }
  6841. !       if (opt_level == 4
  6842. !           && !flag_no_interleave_stack_non_stack)
  6843. !         {
  6844. !           flag_interleave_stack_non_stack = 1;
  6845. !           flag_schedule_insns = 1;
  6846. !         }
  6847. !         }
  6848. !     }
  6849. ! }
  6850.   
  6851.   
  6852.   
  6853.   
  6854. ! optimization_options (level)
  6855. !      int level;
  6856. ! {
  6857. !   opt_level = level;
  6858. !   if (level > 0)
  6859. !     {
  6860. !       flag_opt_reg_use = 1;
  6861. !       flag_reduce_index_givs = 1;
  6862.       }
  6863. !   if (level >= 2)
  6864. !     {
  6865. ! #ifdef INSN_SCHEDULING
  6866. !       flag_schedule_insns = 0;
  6867. !       flag_schedule_insns_after_reload = 0;
  6868. ! #endif
  6869. !     }
  6870. !   if (level >= 3)
  6871. !     {
  6872. !       flag_inline_functions = 1;
  6873. !       flag_jump_back = 1;
  6874. !       flag_copy_prop = 1;
  6875. !       flag_compare_elim = 1;
  6876. !       flag_sftwr_pipe = 1;
  6877. !       flag_omit_frame_pointer = 1;
  6878. !       /*flag_reg_reg_copy_opt = 1; */
  6879. !       flag_opt_reg_stack = 1;
  6880. !       /*flag_loop_after_global = 1; */
  6881. !       flag_peep_spills = 1;
  6882. !       flag_replace_stack_mem = 1;
  6883. !       flag_opt_jumps_out = 1;
  6884. !       flag_replace_mem = 1;
  6885. !       flag_correct_cse_mistakes = 1;
  6886. !       flag_push_load_into_loop = 1;
  6887. !       flag_replace_reload_regs = 1;
  6888. !       flag_sign_extension_elim = 1;
  6889. !       flag_lift_stores = 1;
  6890. !       flag_runtime_lift_stores = 1;
  6891. !     }
  6892. !   if (level >= 4)
  6893. !     {
  6894. ! #ifdef INSN_SCHEDULING
  6895. !       flag_schedule_insns_after_reload = 1;
  6896. !       flag_swap_for_agi = 1;
  6897. !       if (TARGET_PENTIUM)
  6898. !     {
  6899. !           /*flag_risc = 1; */
  6900. !       flag_risc_const = 1;
  6901. !       /*flag_recombine = 1;*/
  6902. !       if (level == 4)
  6903. !         {
  6904. !           flag_schedule_stack_reg_insns = 1;
  6905. !           flag_schedule_insns = 1;
  6906. !         }
  6907. !     }
  6908. ! #endif
  6909. !     }
  6910. !   if (level >= 5)
  6911. !     {
  6912. ! #ifdef INSN_SCHEDULING
  6913. !       flag_schedule_insns = 1;
  6914. ! #endif
  6915. !     }
  6916. !   if (flag_no_risc)
  6917. !     flag_risc = 0;
  6918. !   if (flag_no_risc_const)
  6919. !     flag_risc_const = 0;
  6920. !   if (flag_no_recombine)
  6921. !     flag_recombine = 0;
  6922. !   if (flag_no_risc_mem_dest)
  6923. !     flag_risc_mem_dest = 0;
  6924.   }
  6925.   
  6926. ! /* intel1 */
  6927.   
  6928. ! int
  6929. ! is_fp_insn (insn)
  6930. !      rtx insn;
  6931.   {
  6932. !   if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
  6933. !       && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
  6934. !       || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode))
  6935. !     {
  6936. !       return (1);
  6937. !     }
  6938. !   return (0);
  6939. ! }
  6940.   
  6941.   
  6942. ! /*
  6943. !   Return 1 if the mode of the SET_DEST of insn is floating point
  6944. !   and it is not an fld or a move from memory to memory.
  6945. !   Otherwise return 0
  6946. ! */
  6947. ! int
  6948. ! is_fp_dest (insn)
  6949. !      rtx insn;
  6950.   {
  6951. !   if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
  6952. !       && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
  6953. !       || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode)
  6954. !       && GET_CODE (SET_DEST (PATTERN (insn))) == REG
  6955. !       && REGNO (SET_DEST (PATTERN (insn))) >= FIRST_FLOAT_REG
  6956. !       && GET_CODE (SET_SRC (insn)) != MEM
  6957. !      )
  6958. !     {
  6959. !       return (1);
  6960. !     }
  6961. !   return (0);
  6962.   }
  6963.   
  6964. ! /*
  6965. !   Return 1 if the mode of the SET_DEST floating point and is memory
  6966. !   and the source is a register.  
  6967. ! */
  6968. ! int
  6969. ! is_fp_store (insn)
  6970. !      rtx insn;
  6971.   {
  6972. !   if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
  6973. !       && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
  6974. !       || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode)
  6975. !       && GET_CODE (SET_DEST (PATTERN (insn))) == MEM
  6976. !       && GET_CODE (SET_SRC (PATTERN (insn))) == REG
  6977. !      )
  6978. !     {
  6979. !       return (1);
  6980. !     }
  6981. !   return (0);
  6982.   }
  6983.   
  6984.   
  6985. ! /*
  6986. !   Return 1 if dep_insn sets a register which insn uses as a base
  6987. !   or index to reference memory.
  6988. !   otherwise return 0
  6989. ! */
  6990. ! int
  6991. ! agi_dependent (insn, dep_insn)
  6992. !      rtx insn, dep_insn;
  6993.   {
  6994. !   if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET
  6995. !       && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG)
  6996. !     {
  6997. !       return (reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn)), insn));
  6998. !     }
  6999. !   if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET
  7000. !       && GET_CODE (SET_DEST (PATTERN (dep_insn))) == MEM
  7001. !       && push_operand (SET_DEST (PATTERN (dep_insn)),
  7002. !                        GET_MODE (SET_DEST (PATTERN (dep_insn))))
  7003. !      )
  7004. !     {
  7005. !       return (reg_mentioned_in_mem (stack_pointer_rtx, insn));
  7006. !     }
  7007. !   
  7008. !   return (0);
  7009. ! }
  7010.   
  7011. ! /*
  7012. !   Return 1 if reg is used in rtl as a base or index for a memory ref
  7013. !   otherwise return 0.
  7014. ! */
  7015. ! int
  7016. ! reg_mentioned_in_mem (reg, rtl)
  7017. !      rtx reg, rtl;
  7018. ! {
  7019. !   register char *fmt;
  7020. !   register int i;
  7021. !   register enum rtx_code code;
  7022.   
  7023. !   if (rtl == NULL)
  7024. !     return (0);
  7025.   
  7026. !   code = GET_CODE (rtl);
  7027.   
  7028. !   switch (code)
  7029. !     {
  7030. !     case HIGH:
  7031. !     case CONST_INT:
  7032. !     case CONST:
  7033. !     case CONST_DOUBLE:
  7034. !     case SYMBOL_REF:
  7035. !     case LABEL_REF:
  7036. !     case PC:
  7037. !     case CC0:
  7038. !     case SUBREG:
  7039. !       return (0);
  7040.   
  7041.   
  7042. !     }
  7043.   
  7044. !   if (code == MEM && reg_mentioned_p (reg, rtl))
  7045. !     {
  7046. !       return (1);
  7047. !     }
  7048. !   fmt = GET_RTX_FORMAT (code);
  7049. !   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  7050. !     {
  7051. !       if (fmt[i] == 'E')
  7052. !     {
  7053. !       register int j;
  7054. !       for (j = XVECLEN (rtl, i) - 1; j >= 0; j--)
  7055. !         if (reg_mentioned_in_mem (reg, XVECEXP (rtl, i, j)))
  7056. !           return 1;
  7057. !     }
  7058. !       else if (fmt[i] == 'e'
  7059. !            && reg_mentioned_in_mem (reg, XEXP (rtl, i)))
  7060. !     return 1;
  7061. !     }
  7062. !   return (0);
  7063.   }
  7064. diff -rNci gcc-2.7.2/config/i386/i386.h gcc-2.7.2p/config/i386/i386.h
  7065. *** gcc-2.7.2/config/i386/i386.h    Fri Sep 22 22:42:57 1995
  7066. --- gcc-2.7.2p/config/i386/i386.h    Tue Jan 23 10:31:11 1996
  7067. ***************
  7068. *** 2,7 ****
  7069. --- 2,10 ----
  7070.      (386, 486, Pentium).
  7071.      Copyright (C) 1988, 1992, 1994, 1995 Free Software Foundation, Inc.
  7072.   
  7073. +    Pentium cpu support and other enhancements by Tevi Devor Intel Corp.
  7074. +    (tevi@iil.intel.com).
  7075.   This file is part of GNU CC.
  7076.   
  7077.   GNU CC is free software; you can redistribute it and/or modify
  7078. ***************
  7079. *** 56,179 ****
  7080.   /* Run-time compilation parameters selecting different hardware subsets.  */
  7081.   
  7082.   extern int target_flags;
  7083.   
  7084.   /* Macros used in the machine description to test the flags.  */
  7085.   
  7086.   /* configure can arrange to make this 2, to force a 486.  */
  7087.   #ifndef TARGET_CPU_DEFAULT
  7088. ! #define TARGET_CPU_DEFAULT 0
  7089.   #endif
  7090.   
  7091. ! /* Masks for the -m switches */
  7092. ! #define MASK_80387        000000000001    /* Hardware floating point */
  7093. ! #define MASK_486        000000000002    /* 80486 specific */
  7094. ! #define MASK_NOTUSED1        000000000004    /* bit not currently used */
  7095. ! #define MASK_RTD        000000000010    /* Use ret that pops args */
  7096. ! #define MASK_ALIGN_DOUBLE    000000000020    /* align doubles to 2 word boundary */
  7097. ! #define MASK_SVR3_SHLIB        000000000040    /* Uninit locals into bss */
  7098. ! #define MASK_IEEE_FP        000000000100    /* IEEE fp comparisons */
  7099. ! #define MASK_FLOAT_RETURNS    000000000200    /* Return float in st(0) */
  7100. ! #define MASK_NO_FANCY_MATH_387    000000000400    /* Disable sin, cos, sqrt */
  7101. !                         /* Temporary codegen switches */
  7102. ! #define MASK_DEBUG_ADDR        000001000000    /* Debug GO_IF_LEGITIMATE_ADDRESS */
  7103. ! #define MASK_NO_WIDE_MULTIPLY    000002000000    /* Disable 32x32->64 multiplies */
  7104. ! #define MASK_NO_MOVE        000004000000    /* Don't generate mem->mem */
  7105. ! #define MASK_DEBUG_ARG        000010000000    /* Debug function_arg */   
  7106. ! /* Use the floating point instructions */
  7107. ! #define TARGET_80387 (target_flags & MASK_80387)
  7108.   /* Compile using ret insn that pops args.
  7109.      This will not work unless you use prototypes at least
  7110.      for all functions that can take varying numbers of args.  */  
  7111. ! #define TARGET_RTD (target_flags & MASK_RTD)
  7112.   
  7113.   /* Align doubles to a two word boundary.  This breaks compatibility with
  7114.      the published ABI's for structures containing doubles, but produces
  7115.      faster code on the pentium.  */
  7116. ! #define TARGET_ALIGN_DOUBLE (target_flags & MASK_ALIGN_DOUBLE)
  7117.   
  7118.   /* Put uninitialized locals into bss, not data.
  7119.      Meaningful only on svr3.  */
  7120. ! #define TARGET_SVR3_SHLIB (target_flags & MASK_SVR3_SHLIB)
  7121.   
  7122.   /* Use IEEE floating point comparisons.  These handle correctly the cases
  7123.      where the result of a comparison is unordered.  Normally SIGFPE is
  7124.      generated in such cases, in which case this isn't needed.  */
  7125. ! #define TARGET_IEEE_FP (target_flags & MASK_IEEE_FP)
  7126.   
  7127.   /* Functions that return a floating point value may return that value
  7128.      in the 387 FPU or in 386 integer registers.  If set, this flag causes
  7129.      the 387 to be used, which is compatible with most calling conventions. */
  7130. ! #define TARGET_FLOAT_RETURNS_IN_80387 (target_flags & MASK_FLOAT_RETURNS)
  7131. ! /* Disable generation of FP sin, cos and sqrt operations for 387.
  7132. !    This is because FreeBSD lacks these in the math-emulator-code */
  7133. ! #define TARGET_NO_FANCY_MATH_387 (target_flags & MASK_NO_FANCY_MATH_387)
  7134. ! /* Temporary switches for tuning code generation */
  7135. ! /* Disable 32x32->64 bit multiplies that are used for long long multiplies
  7136. !    and division by constants, but sometimes cause reload problems.  */
  7137. ! #define TARGET_NO_WIDE_MULTIPLY (target_flags & MASK_NO_WIDE_MULTIPLY)
  7138. ! #define TARGET_WIDE_MULTIPLY (!TARGET_NO_WIDE_MULTIPLY)
  7139. ! /* Debug GO_IF_LEGITIMATE_ADDRESS */
  7140. ! #define TARGET_DEBUG_ADDR (target_flags & MASK_DEBUG_ADDR)
  7141.   
  7142.   /* Debug FUNCTION_ARG macros */
  7143. ! #define TARGET_DEBUG_ARG (target_flags & MASK_DEBUG_ARG)
  7144.   
  7145. ! /* Hack macros for tuning code generation */
  7146. ! #define TARGET_MOVE    ((target_flags & MASK_NO_MOVE) == 0)    /* Don't generate memory->memory */
  7147.   
  7148. ! /* Specific hardware switches */
  7149. ! #define TARGET_486    (target_flags & MASK_486)    /* 80486DX, 80486SX, 80486DX[24] */
  7150. ! #define TARGET_386    (!TARGET_486)             /* 80386 */
  7151. ! #define TARGET_SWITCHES                            \
  7152. ! { { "80387",             MASK_80387 },                \
  7153. !   { "no-80387",            -MASK_80387 },                \
  7154. !   { "hard-float",         MASK_80387 },                \
  7155. !   { "soft-float",        -MASK_80387 },                \
  7156. !   { "no-soft-float",         MASK_80387 },                \
  7157. !   { "386",            -MASK_486 },                \
  7158. !   { "no-386",             MASK_486 },                \
  7159. !   { "486",             MASK_486 },                \
  7160. !   { "no-486",            -MASK_486 },                \
  7161. !   { "rtd",             MASK_RTD },                \
  7162. !   { "no-rtd",            -MASK_RTD },                \
  7163. !   { "align-double",         MASK_ALIGN_DOUBLE },            \
  7164. !   { "no-align-double",        -MASK_ALIGN_DOUBLE },            \
  7165. !   { "svr3-shlib",         MASK_SVR3_SHLIB },            \
  7166. !   { "no-svr3-shlib",        -MASK_SVR3_SHLIB },            \
  7167. !   { "ieee-fp",             MASK_IEEE_FP },            \
  7168. !   { "no-ieee-fp",        -MASK_IEEE_FP },            \
  7169. !   { "fp-ret-in-387",         MASK_FLOAT_RETURNS },            \
  7170. !   { "no-fp-ret-in-387",        -MASK_FLOAT_RETURNS },            \
  7171. !   { "no-fancy-math-387",     MASK_NO_FANCY_MATH_387 },        \
  7172. !   { "fancy-math-387",        -MASK_NO_FANCY_MATH_387 },        \
  7173. !   { "no-wide-multiply",         MASK_NO_WIDE_MULTIPLY },        \
  7174. !   { "wide-multiply",        -MASK_NO_WIDE_MULTIPLY },        \
  7175. !   { "debug-addr",         MASK_DEBUG_ADDR },            \
  7176. !   { "no-debug-addr",        -MASK_DEBUG_ADDR },            \
  7177. !   { "move",            -MASK_NO_MOVE },            \
  7178. !   { "no-move",             MASK_NO_MOVE },            \
  7179. !   { "debug-arg",         MASK_DEBUG_ARG },            \
  7180. !   { "no-debug-arg",        -MASK_DEBUG_ARG },            \
  7181. !   SUBTARGET_SWITCHES                            \
  7182. !   { "", TARGET_DEFAULT | TARGET_CPU_DEFAULT}}
  7183. ! /* This macro is similar to `TARGET_SWITCHES' but defines names of
  7184. !    command options that have values.  Its definition is an
  7185. !    initializer with a subgrouping for each command option.
  7186. !    Each subgrouping contains a string constant, that defines the
  7187. !    fixed part of the option name, and the address of a variable.  The
  7188. !    variable, type `char *', is set to the variable part of the given
  7189. !    option if the fixed part matches.  The actual option name is made
  7190. !    by appending `-m' to the specified name.  */
  7191.   #define TARGET_OPTIONS                            \
  7192.   { { "reg-alloc=",    &i386_reg_alloc_order },            \
  7193.     { "regparm=",        &i386_regparm_string },                \
  7194. --- 59,196 ----
  7195.   /* Run-time compilation parameters selecting different hardware subsets.  */
  7196.   
  7197.   extern int target_flags;
  7198. + /* Which processor to schedule for. intel1 */
  7199. + enum processor_type {
  7200. +   PROCESSOR_DEFAULT,
  7201. +   PROCESSOR_386,
  7202. +   PROCESSOR_486,
  7203. +   PROCESSOR_PENTIUM
  7204. + };
  7205. + extern enum processor_type x86_cpu;    /* which cpu are we scheduling for */
  7206. + /* intel1 */
  7207. + #define REDUCE_INDEX (TARGET_486 || TARGET_PENTIUM)
  7208. + #define SAVE_ON_REGS 1
  7209. + #define MAX_DEST_ADDR_GIVS 5
  7210. + #define PREFER_JUMP_NOT_TAKEN 1
  7211. + #define PREFER_CONST_IN_REG 1
  7212. + #define IGNORE_NON_DATA_DEP 1
  7213. + #define STORE_NOT_SET_CC0 1
  7214. + #define NO_CROSS_JUMP_ON_LOOP_ENTRY 1
  7215. + #define AGI 1
  7216. + /* #define SPILL1 */
  7217. + #define EXPENSIVE_OPS(x) \
  7218. +    ( GET_CODE(x)==MULT ? \
  7219. +        ((GET_CODE (XEXP (x, 1)) == CONST_INT && \
  7220. +     exact_log2 (INTVAL (XEXP (x, 1))) >= 0) ? 0 : 1) : \
  7221. +     (GET_CODE(x)==DIV || GET_CODE(x)==UDIV || \
  7222. +      GET_CODE(x)==MOD || GET_CODE(x)==UMOD ))
  7223. + #define NO_STACK_REG_REORDER (!TARGET_PENTIUM)
  7224. + #define STACK_REG_REORDER \
  7225. +     ((TARGET_PENTIUM) && reload_completed == 0 && flag_schedule_stack_reg_insns)
  7226. + #define STACK_NON_STACK_INTERLEAVE \
  7227. +     (reload_completed == 0 && flag_interleave_stack_non_stack)
  7228. +     
  7229. + #define IS_RISC_MODE(mode) (((mode) == QImode || (mode) == SImode))
  7230. + /* Number of extra pseudo registers we allocate for so that reg-stack
  7231. +    can replace fld's and fstps with movs
  7232. + */
  7233. + #define SPARE_REGS 5
  7234. + #define OVERRIDE_OPTIONS override_options()
  7235.   
  7236.   /* Macros used in the machine description to test the flags.  */
  7237.   
  7238.   /* configure can arrange to make this 2, to force a 486.  */
  7239.   #ifndef TARGET_CPU_DEFAULT
  7240. ! #define TARGET_CPU_DEFAULT TARGET_PENTIUM_SWITCH
  7241.   #endif
  7242.   
  7243. ! /* Compile 80387 insns for floating point (not library calls).  */
  7244. ! #define TARGET_80387 (target_flags & 1)
  7245.   /* Compile using ret insn that pops args.
  7246.      This will not work unless you use prototypes at least
  7247.      for all functions that can take varying numbers of args.  */  
  7248. ! #define TARGET_RTD (target_flags & 8)
  7249.   
  7250.   /* Align doubles to a two word boundary.  This breaks compatibility with
  7251.      the published ABI's for structures containing doubles, but produces
  7252.      faster code on the pentium.  */
  7253. ! #define TARGET_ALIGN_DOUBLE (target_flags & 020)
  7254.   
  7255.   /* Put uninitialized locals into bss, not data.
  7256.      Meaningful only on svr3.  */
  7257. ! #define TARGET_SVR3_SHLIB (target_flags & 040)
  7258.   
  7259.   /* Use IEEE floating point comparisons.  These handle correctly the cases
  7260.      where the result of a comparison is unordered.  Normally SIGFPE is
  7261.      generated in such cases, in which case this isn't needed.  */
  7262. ! #define TARGET_IEEE_FP (target_flags & 0100)
  7263.   
  7264.   /* Functions that return a floating point value may return that value
  7265.      in the 387 FPU or in 386 integer registers.  If set, this flag causes
  7266.      the 387 to be used, which is compatible with most calling conventions. */
  7267. ! #define TARGET_FLOAT_RETURNS_IN_80387 (target_flags & 0200)
  7268.   
  7269.   /* Debug FUNCTION_ARG macros */
  7270. ! #define TARGET_DEBUG_ARG (target_flags & 000010000000)
  7271. ! /* Macro to define tables used to set the flags.
  7272. !    This is a list in braces of pairs in braces,
  7273. !    each pair being { "NAME", VALUE }
  7274. !    where VALUE is the bits to set or minus the bits to clear.
  7275. !    An empty string NAME is used to identify the default VALUE.  */
  7276. ! /* intel1 */
  7277. ! #define TARGET_486_SWITCH 2
  7278. ! #define TARGET_486 (target_flags & TARGET_486_SWITCH)
  7279. ! /* Compile code for a Pentium. intel1 */
  7280. ! #define TARGET_PENTIUM_SWITCH 4
  7281. ! #define TARGET_PENTIUM (target_flags & TARGET_PENTIUM_SWITCH)
  7282. ! /* Compile code for an i386. intel1 */
  7283. ! #define TARGET_386_SWITCH 0400
  7284. ! #define TARGET_386 (target_flags & TARGET_386_SWITCH)
  7285. ! /* Compile code for a Blend. intel1 */
  7286. ! #define TARGET_BLEND_SWITCH 02000
  7287. ! #define TARGET_BLEND (target_flags & TARGET_BLEND_SWITCH)
  7288. ! #define TARGET_X ((TARGET_386) | (TARGET_486) | (TARGET_PENTIUM))
  7289. ! #define USE_CPU ((TARGET_X) ? (TARGET_X) : TARGET_CPU_DEFAULT)
  7290. ! #define TARGET_SWITCHES  \
  7291. !   { { "80387", 1},                \
  7292. !     { "no-80387", -1},                \
  7293. !     { "soft-float", -1},            \
  7294. !     { "no-soft-float", 1},            \
  7295. !     { "486", 2},                \
  7296. !     { "no-486", -2},                \
  7297. !     { "386", 0400},                \
  7298. !     { "pentium", 4},                \
  7299. !     { "blend", 02000},                \
  7300. !     { "rtd", 8},                \
  7301. !     { "no-rtd", -8},                \
  7302. !     { "align-double", 020},                \
  7303. !     { "no-align-double", -020},            \
  7304. !     { "svr3-shlib", 040},            \
  7305. !     { "no-svr3-shlib", -040},            \
  7306. !     { "ieee-fp", 0100},                \
  7307. !     { "no-ieee-fp", -0100},            \
  7308. !     { "fp-ret-in-387", 0200},            \
  7309. !     { "no-fp-ret-in-387", -0200},        \
  7310. !     { "debug-addr", 000010000000 },            \
  7311. !     { "no-debug-addr", -000010000000},            \
  7312. !     SUBTARGET_SWITCHES                          \
  7313. !     { "", TARGET_DEFAULT }}
  7314.   
  7315. ! /* This is meant to be redefined in the host dependent files */
  7316. ! #define SUBTARGET_SWITCHES
  7317.   
  7318.   #define TARGET_OPTIONS                            \
  7319.   { { "reg-alloc=",    &i386_reg_alloc_order },            \
  7320.     { "regparm=",        &i386_regparm_string },                \
  7321. ***************
  7322. *** 183,215 ****
  7323.     SUBTARGET_OPTIONS                            \
  7324.   }
  7325.   
  7326. ! /* Sometimes certain combinations of command options do not make
  7327. !    sense on a particular target machine.  You can define a macro
  7328. !    `OVERRIDE_OPTIONS' to take account of this.  This macro, if
  7329. !    defined, is executed once just after all the command options have
  7330. !    been parsed.
  7331.   
  7332. !    Don't use this macro to turn on various extra optimizations for
  7333. !    `-O'.  That is what `OPTIMIZATION_OPTIONS' is for.  */
  7334.   
  7335. ! #define OVERRIDE_OPTIONS override_options ()
  7336.   
  7337. - /* These are meant to be redefined in the host dependent files */
  7338. - #define SUBTARGET_SWITCHES
  7339. - #define SUBTARGET_OPTIONS
  7340.   
  7341.   /* target machine storage layout */
  7342.   
  7343.   /* Define for XFmode extended real floating point support.
  7344.      This will automatically cause REAL_ARITHMETIC to be defined.  */
  7345.   #define LONG_DOUBLE_TYPE_SIZE 96
  7346.   /* Define if you don't want extended real, but do want to use the
  7347.      software floating point emulator for REAL_ARITHMETIC and
  7348.      decimal <-> binary conversion. */
  7349.   /* #define REAL_ARITHMETIC */
  7350.   
  7351.   /* Define this if most significant byte of a word is the lowest numbered.  */
  7352.   /* That is true on the 80386.  */
  7353.   
  7354. --- 200,231 ----
  7355.     SUBTARGET_OPTIONS                            \
  7356.   }
  7357.   
  7358. ! #define SUBTARGET_OPTIONS
  7359. ! /* intel1 */
  7360.   
  7361. ! #define SUB_TARGET_STRING \
  7362. ! (TARGET_PENTIUM ? "Pentium"  : (TARGET_386 ? "Intel386" : "Intel486"))
  7363.   
  7364. ! #define SUB_TARGET_VERSION fprintf (stderr, " [%s cpu] ", SUB_TARGET_STRING)
  7365.   
  7366.   
  7367. ! /* Define this to change the optimizations performed by default.  */
  7368. ! #define OPTIMIZATION_OPTIONS(LEVEL)    \
  7369. ! optimization_options(LEVEL)
  7370.   /* target machine storage layout */
  7371.   
  7372.   /* Define for XFmode extended real floating point support.
  7373.      This will automatically cause REAL_ARITHMETIC to be defined.  */
  7374.   #define LONG_DOUBLE_TYPE_SIZE 96
  7375. !  
  7376.   /* Define if you don't want extended real, but do want to use the
  7377.      software floating point emulator for REAL_ARITHMETIC and
  7378.      decimal <-> binary conversion. */
  7379.   /* #define REAL_ARITHMETIC */
  7380.   
  7381.   /* Define this if most significant byte of a word is the lowest numbered.  */
  7382.   /* That is true on the 80386.  */
  7383.   
  7384. ***************
  7385. *** 265,270 ****
  7386. --- 281,289 ----
  7387.      aligned on 64 bit boundaries. */
  7388.   #define BIGGEST_ALIGNMENT (TARGET_ALIGN_DOUBLE ? 64 : 32)
  7389.   
  7390. + /* intel1 - align DFmode constants and nonaggregates */
  7391. + #define ALIGN_DFmode (!TARGET_386)
  7392.   /* Set this non-zero if move instructions will actually fail to work
  7393.      when given unaligned data.  */
  7394.   #define STRICT_ALIGNMENT 0
  7395. ***************
  7396. *** 292,297 ****
  7397. --- 311,318 ----
  7398.      for details. */
  7399.   
  7400.   #define STACK_REGS
  7401. + /* intel1 */
  7402. + #define IS_STACK_MODE(mode) (mode==DFmode || mode==SFmode)
  7403.   
  7404.   /* Number of actual hardware registers.
  7405.      The hardware registers are assigned numbers for the compiler
  7406. ***************
  7407. *** 329,372 ****
  7408.   /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \
  7409.   {  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1 }
  7410.   
  7411. - /* Order in which to allocate registers.  Each register must be
  7412. -    listed once, even those in FIXED_REGISTERS.  List frame pointer
  7413. -    late and fixed registers last.  Note that, in general, we prefer
  7414. -    registers listed in CALL_USED_REGISTERS, keeping the others
  7415. -    available for storage of persistent values.
  7416. -    Three different versions of REG_ALLOC_ORDER have been tried:
  7417. -    If the order is edx, ecx, eax, ... it produces a slightly faster compiler,
  7418. -    but slower code on simple functions returning values in eax.
  7419. -    If the order is eax, ecx, edx, ... it causes reload to abort when compiling
  7420. -    perl 4.036 due to not being able to create a DImode register (to hold a 2
  7421. -    word union).
  7422. -    If the order is eax, edx, ecx, ... it produces better code for simple
  7423. -    functions, and a slightly slower compiler.  Users complained about the code
  7424. -    generated by allocating edx first, so restore the 'natural' order of things. */
  7425. - #define REG_ALLOC_ORDER \
  7426. - /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \
  7427. - {  0, 1, 2, 3, 4, 5, 6, 7, 8,  9, 10, 11, 12, 13, 14, 15, 16 }
  7428. - /* A C statement (sans semicolon) to choose the order in which to
  7429. -    allocate hard registers for pseudo-registers local to a basic
  7430. -    block.
  7431. -    Store the desired register order in the array `reg_alloc_order'.
  7432. -    Element 0 should be the register to allocate first; element 1, the
  7433. -    next register; and so on.
  7434. -    The macro body should not assume anything about the contents of
  7435. -    `reg_alloc_order' before execution of the macro.
  7436. -    On most machines, it is not necessary to define this macro.  */
  7437. - #define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
  7438.   /* Macro to conditionally modify fixed_regs/call_used_regs.  */
  7439.   #define CONDITIONAL_REGISTER_USAGE            \
  7440.     {                            \
  7441. --- 350,355 ----
  7442. ***************
  7443. *** 408,413 ****
  7444. --- 391,399 ----
  7445.   /* The casts to int placate a compiler on a microvax,
  7446.      for cross-compiler testing.  */
  7447.   
  7448. + /* intel1 - added case of (REGNO)==16 (gbug12)*/
  7449. + /*   : (REGNO) == 16 ? 1                             \ */
  7450.   #define HARD_REGNO_MODE_OK(REGNO, MODE) \
  7451.     ((REGNO) < 2 ? 1                        \
  7452.      : (REGNO) < 4 ? 1                        \
  7453. ***************
  7454. *** 479,505 ****
  7455.   /* Place in which caller passes the structure value address.
  7456.      0 means push the value on the stack like an argument.  */
  7457.   #define STRUCT_VALUE 0
  7458. - /* A C expression which can inhibit the returning of certain function
  7459. -    values in registers, based on the type of value.  A nonzero value
  7460. -    says to return the function value in memory, just as large
  7461. -    structures are always returned.  Here TYPE will be a C expression
  7462. -    of type `tree', representing the data type of the value.
  7463. -    Note that values of mode `BLKmode' must be explicitly handled by
  7464. -    this macro.  Also, the option `-fpcc-struct-return' takes effect
  7465. -    regardless of this macro.  On most systems, it is possible to
  7466. -    leave the macro undefined; this causes a default definition to be
  7467. -    used, whose value is the constant 1 for `BLKmode' values, and 0
  7468. -    otherwise.
  7469. -    Do not use this macro to indicate that structures and unions
  7470. -    should always be returned in memory.  You should instead use
  7471. -    `DEFAULT_PCC_STRUCT_RETURN' to indicate this.  */
  7472. - #define RETURN_IN_MEMORY(TYPE) \
  7473. -   ((TYPE_MODE (TYPE) == BLKmode) || int_size_in_bytes (TYPE) > 12)
  7474.   
  7475.   /* Define the classes of registers for register constraints in the
  7476.      machine description.  Also define ranges of constants.
  7477. --- 465,470 ----
  7478. ***************
  7479. *** 529,535 ****
  7480.   {
  7481.     NO_REGS,
  7482.     AREG, DREG, CREG, BREG,
  7483. -   AD_REGS,            /* %eax/%edx for DImode */
  7484.     Q_REGS,            /* %eax %ebx %ecx %edx */
  7485.     SIREG, DIREG,
  7486.     INDEX_REGS,            /* %eax %ebx %ecx %edx %esi %edi %ebp */
  7487. --- 494,499 ----
  7488. ***************
  7489. *** 548,554 ****
  7490.   #define REG_CLASS_NAMES \
  7491.   {  "NO_REGS",                \
  7492.      "AREG", "DREG", "CREG", "BREG",    \
  7493. -    "AD_REGS",                \
  7494.      "Q_REGS",                \
  7495.      "SIREG", "DIREG",            \
  7496.      "INDEX_REGS",            \
  7497. --- 512,517 ----
  7498. ***************
  7499. *** 564,573 ****
  7500.   #define REG_CLASS_CONTENTS \
  7501.   {      0,                            \
  7502.        0x1,    0x2,  0x4,     0x8,    /* AREG, DREG, CREG, BREG */    \
  7503. -      0x3,            /* AD_REGS */            \
  7504.        0xf,            /* Q_REGS */            \
  7505.       0x10,   0x20,        /* SIREG, DIREG */        \
  7506. !  0x07f,                /* INDEX_REGS */        \
  7507.    0x100ff,            /* GENERAL_REGS */        \
  7508.     0x0100, 0x0200,        /* FP_TOP_REG, FP_SECOND_REG */    \
  7509.     0xff00,            /* FLOAT_REGS */        \
  7510. --- 527,535 ----
  7511.   #define REG_CLASS_CONTENTS \
  7512.   {      0,                            \
  7513.        0x1,    0x2,  0x4,     0x8,    /* AREG, DREG, CREG, BREG */    \
  7514.        0xf,            /* Q_REGS */            \
  7515.       0x10,   0x20,        /* SIREG, DIREG */        \
  7516. !  0x1007f,            /* INDEX_REGS */        \
  7517.    0x100ff,            /* GENERAL_REGS */        \
  7518.     0x0100, 0x0200,        /* FP_TOP_REG, FP_SECOND_REG */    \
  7519.     0xff00,            /* FLOAT_REGS */        \
  7520. ***************
  7521. *** 578,583 ****
  7522. --- 540,546 ----
  7523.      reg number REGNO.  This could be a conditional expression
  7524.      or could index an array.  */
  7525.   
  7526. + extern enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
  7527.   #define REGNO_REG_CLASS(REGNO) (regclass_map[REGNO])
  7528.   
  7529.   /* When defined, the compiler allows registers explicitly used in the
  7530. ***************
  7531. *** 635,643 ****
  7532.      (C) == 'b' ? BREG :                        \
  7533.      (C) == 'c' ? CREG :                        \
  7534.      (C) == 'd' ? DREG :                        \
  7535. -    (C) == 'A' ? AD_REGS :                    \
  7536.      (C) == 'D' ? DIREG :                        \
  7537. !    (C) == 'S' ? SIREG : NO_REGS)
  7538.   
  7539.   /* The letters I, J, K, L and M in a register constraint string
  7540.      can be used to stand for particular ranges of immediate operands.
  7541. --- 598,605 ----
  7542.      (C) == 'b' ? BREG :                        \
  7543.      (C) == 'c' ? CREG :                        \
  7544.      (C) == 'd' ? DREG :                        \
  7545.      (C) == 'D' ? DIREG :                        \
  7546. !    (C) == 'S' ? SIREG : NO_REGS) /* intel1 changed to e from S */
  7547.   
  7548.   /* The letters I, J, K, L and M in a register constraint string
  7549.      can be used to stand for particular ranges of immediate operands.
  7550. ***************
  7551. *** 649,654 ****
  7552. --- 611,617 ----
  7553.      J is for DImode shifts.
  7554.      K and L are for an `andsi' optimization.
  7555.      M is for shifts that can be executed by the "lea" opcode.
  7556. +    O is for block moves intel1
  7557.      */
  7558.   
  7559.   #define CONST_OK_FOR_LETTER_P(VALUE, C)  \
  7560. ***************
  7561. *** 657,662 ****
  7562. --- 620,626 ----
  7563.      (C) == 'K' ? (VALUE) == 0xff :        \
  7564.      (C) == 'L' ? (VALUE) == 0xffff :        \
  7565.      (C) == 'M' ? (VALUE) >= 0 && (VALUE) <= 3 :    \
  7566. +    (C) == 'O' ? (VALUE) >= 0 && (VALUE) <= 32 :    \
  7567.      (C) == 'N' ? (VALUE) >= 0 && (VALUE) <= 255 :\
  7568.      0)
  7569.   
  7570. ***************
  7571. *** 710,742 ****
  7572.   #define CLASS_MAX_NREGS(CLASS, MODE)    \
  7573.    (FLOAT_CLASS_P (CLASS) ? 1 :        \
  7574.     ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  7575.   
  7576. ! /* A C expression whose value is nonzero if pseudos that have been
  7577. !    assigned to registers of class CLASS would likely be spilled
  7578. !    because registers of CLASS are needed for spill registers.
  7579. !    The default value of this macro returns 1 if CLASS has exactly one
  7580. !    register and zero otherwise.  On most machines, this default
  7581. !    should be used.  Only define this macro to some other expression
  7582. !    if pseudo allocated by `local-alloc.c' end up in memory because
  7583. !    their hard registers were needed for spill registers.  If this
  7584. !    macro returns nonzero for those classes, those pseudos will only
  7585. !    be allocated by `global.c', which knows how to reallocate the
  7586. !    pseudo to another register.  If there would not be another
  7587. !    register available for reallocation, you should not change the
  7588. !    definition of this macro since the only effect of such a
  7589. !    definition would be to slow down register allocation.  */
  7590. ! #define CLASS_LIKELY_SPILLED_P(CLASS)                    \
  7591. !   (((CLASS) == AREG)                            \
  7592. !    || ((CLASS) == DREG)                            \
  7593. !    || ((CLASS) == CREG)                            \
  7594. !    || ((CLASS) == BREG)                            \
  7595. !    || ((CLASS) == AD_REGS)                        \
  7596. !    || ((CLASS) == SIREG)                        \
  7597. !    || ((CLASS) == DIREG))
  7598.   
  7599.   /* Stack layout; function entry, exit and calling.  */
  7600.   
  7601.   /* Define this if pushing a word on the stack
  7602. --- 674,764 ----
  7603.   #define CLASS_MAX_NREGS(CLASS, MODE)    \
  7604.    (FLOAT_CLASS_P (CLASS) ? 1 :        \
  7605.     ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  7606.   
  7607. ! /* A C statement (sans semicolon) to update the integer variable COST
  7608. !    based on the relationship between INSN that is dependent on
  7609. !    DEP_INSN through the dependence LINK.  The default is to make no
  7610. !    adjustment to COST.  */
  7611. ! #define ADJUST_COST(insn,link,dep_insn,cost)                \
  7612. !   {                                    \
  7613. !     rtx next_inst;                            \
  7614. !     if (GET_CODE (dep_insn) == CALL_INSN)                \
  7615. !       (cost) = 0;                            \
  7616. !         if (GET_CODE (dep_insn) == INSN                    \
  7617. !             && GET_CODE (PATTERN (dep_insn)) == SET            \
  7618. !             && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG        \
  7619. !             && GET_CODE (insn) == INSN                    \
  7620. !             && GET_CODE (PATTERN (insn)) == SET                \
  7621. !             && !reg_overlap_mentioned_p (SET_DEST (PATTERN (dep_insn)),    \
  7622. !                                          SET_SRC (PATTERN (insn))))    \
  7623. !           {                                \
  7624. !             (cost) = 0;                            \
  7625. !           }                                \
  7626. !     if (GET_CODE (insn) == JUMP_INSN)                    \
  7627. !       {                                    \
  7628. !         (cost) = 0;                            \
  7629. !       }                                    \
  7630. !     if (TARGET_PENTIUM)                            \
  7631. !       {                                    \
  7632. !         if (cost !=0 && is_fp_insn (insn) && is_fp_insn (dep_insn)     \
  7633. !             && !is_fp_dest (dep_insn))                    \
  7634. !           {                                \
  7635. !             (cost) = 0;                            \
  7636. !           }                                \
  7637. !         if (agi_dependent (insn, dep_insn))                \
  7638. !           {                                \
  7639. !             (cost) = 3;                            \
  7640. !           }                                \
  7641. !         else if (GET_CODE (insn) == INSN                 \
  7642. !                  && GET_CODE (PATTERN (insn)) == SET            \
  7643. !                  && SET_DEST (PATTERN (insn)) == cc0_rtx        \
  7644. !                  && (next_inst = next_nonnote_insn (insn))        \
  7645. !                  && GET_CODE (next_inst) == JUMP_INSN)            \
  7646. !           { /* compare probably paired with jump */            \
  7647. !             (cost) = 0;                            \
  7648. !           }                                \
  7649. !       }                                    \
  7650. !     else                                \
  7651. !     if(!is_fp_dest (dep_insn))                        \
  7652. !       {                                    \
  7653. !         if(!agi_dependent (insn, dep_insn))                \
  7654. !           (cost) = 0;                            \
  7655. !          else if (TARGET_486)                        \
  7656. !            (cost) = 2;                            \
  7657. !       }                                    \
  7658. !     else                                \
  7659. !     if(is_fp_store (insn) && is_fp_insn (dep_insn)            \
  7660. !        && NEXT_INSN (insn) && NEXT_INSN (NEXT_INSN (insn))        \
  7661. !        && NEXT_INSN (NEXT_INSN (NEXT_INSN (insn)))            \
  7662. !        && (GET_CODE (NEXT_INSN (insn)) == INSN)                \
  7663. !        && (GET_CODE (NEXT_INSN (NEXT_INSN (insn))) == JUMP_INSN)    \
  7664. !        && (GET_CODE (NEXT_INSN (NEXT_INSN (NEXT_INSN (insn))))         \
  7665. !             == NOTE)                            \
  7666. !        && NOTE_LINE_NUMBER (NEXT_INSN (NEXT_INSN (NEXT_INSN (insn))))     \
  7667. !            == NOTE_INSN_LOOP_END)                    \
  7668. !       {                                    \
  7669. !            (cost) = 3;                            \
  7670. !       }                                    \
  7671. !   }                                    
  7672. ! #define ADJUST_BLOCKAGE(last_insn,insn,blockage)            \
  7673. !   {                                    \
  7674. !     if(is_fp_store (last_insn) && is_fp_insn (insn)            \
  7675. !        && NEXT_INSN (last_insn) && NEXT_INSN (NEXT_INSN (last_insn))    \
  7676. !        && NEXT_INSN (NEXT_INSN (NEXT_INSN (last_insn)))            \
  7677. !        && (GET_CODE (NEXT_INSN (last_insn)) == INSN)            \
  7678. !        && (GET_CODE (NEXT_INSN (NEXT_INSN (last_insn))) == JUMP_INSN)    \
  7679. !        && (GET_CODE (NEXT_INSN (NEXT_INSN (NEXT_INSN (last_insn))))     \
  7680. !             == NOTE)                            \
  7681. !        && NOTE_LINE_NUMBER (NEXT_INSN (NEXT_INSN (NEXT_INSN (last_insn))))     \
  7682. !            == NOTE_INSN_LOOP_END)                    \
  7683. !       {                                    \
  7684. !            (blockage) = 3;                        \
  7685. !       }                                    \
  7686. !   }                                    
  7687.   
  7688.   /* Stack layout; function entry, exit and calling.  */
  7689.   
  7690.   /* Define this if pushing a word on the stack
  7691. ***************
  7692. *** 887,988 ****
  7693.       }                                    \
  7694.   }
  7695.   
  7696. - /* A C statement or compound statement to output to FILE some
  7697. -    assembler code to initialize basic-block profiling for the current
  7698. -    object module.  This code should call the subroutine
  7699. -    `__bb_init_func' once per object module, passing it as its sole
  7700. -    argument the address of a block allocated in the object module.
  7701. -    The name of the block is a local symbol made with this statement:
  7702. -     ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0);
  7703. -    Of course, since you are writing the definition of
  7704. -    `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you
  7705. -    can take a short cut in the definition of this macro and use the
  7706. -    name that you know will result.
  7707. -    The first word of this block is a flag which will be nonzero if the
  7708. -    object module has already been initialized.  So test this word
  7709. -    first, and do not call `__bb_init_func' if the flag is nonzero.  */
  7710. - #undef    FUNCTION_BLOCK_PROFILER
  7711. - #define FUNCTION_BLOCK_PROFILER(STREAM, LABELNO)            \
  7712. - do                                    \
  7713. -   {                                    \
  7714. -     static int num_func = 0;                        \
  7715. -     rtx xops[8];                            \
  7716. -     char block_table[80], false_label[80];                \
  7717. -                                     \
  7718. -     ASM_GENERATE_INTERNAL_LABEL (block_table, "LPBX", 0);        \
  7719. -     ASM_GENERATE_INTERNAL_LABEL (false_label, "LPBZ", num_func);    \
  7720. -                                     \
  7721. -     xops[0] = const0_rtx;                        \
  7722. -     xops[1] = gen_rtx (SYMBOL_REF, VOIDmode, block_table);        \
  7723. -     xops[2] = gen_rtx (MEM, Pmode, gen_rtx (SYMBOL_REF, VOIDmode, false_label)); \
  7724. -     xops[3] = gen_rtx (MEM, Pmode, gen_rtx (SYMBOL_REF, VOIDmode, "__bb_init_func")); \
  7725. -     xops[4] = gen_rtx (MEM, Pmode, xops[1]);                \
  7726. -     xops[5] = stack_pointer_rtx;                    \
  7727. -     xops[6] = GEN_INT (4);                        \
  7728. -     xops[7] = gen_rtx (REG, Pmode, 0);    /* eax */            \
  7729. -                                     \
  7730. -     CONSTANT_POOL_ADDRESS_P (xops[1]) = TRUE;                \
  7731. -     CONSTANT_POOL_ADDRESS_P (xops[2]) = TRUE;                \
  7732. -                                     \
  7733. -     output_asm_insn (AS2(cmp%L4,%0,%4), xops);                \
  7734. -     output_asm_insn (AS1(jne,%2), xops);                \
  7735. -                                     \
  7736. -     if (!flag_pic)                            \
  7737. -       output_asm_insn (AS1(push%L1,%1), xops);                \
  7738. -     else                                \
  7739. -       {                                    \
  7740. -     output_asm_insn (AS2 (lea%L7,%a1,%7), xops);            \
  7741. -     output_asm_insn (AS1 (push%L7,%7), xops);            \
  7742. -       }                                    \
  7743. -                                     \
  7744. -     output_asm_insn (AS1(call,%P3), xops);                \
  7745. -     output_asm_insn (AS2(add%L0,%6,%5), xops);                \
  7746. -     ASM_OUTPUT_INTERNAL_LABEL (STREAM, "LPBZ", num_func);        \
  7747. -     num_func++;                                \
  7748. -   }                                    \
  7749. - while (0)
  7750. - /* A C statement or compound statement to increment the count
  7751. -    associated with the basic block number BLOCKNO.  Basic blocks are
  7752. -    numbered separately from zero within each compilation.  The count
  7753. -    associated with block number BLOCKNO is at index BLOCKNO in a
  7754. -    vector of words; the name of this array is a local symbol made
  7755. -    with this statement:
  7756. -     ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 2);
  7757. -    Of course, since you are writing the definition of
  7758. -    `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you
  7759. -    can take a short cut in the definition of this macro and use the
  7760. -    name that you know will result.  */
  7761. - #define BLOCK_PROFILER(STREAM, BLOCKNO)                    \
  7762. - do                                    \
  7763. -   {                                    \
  7764. -     rtx xops[1], cnt_rtx;                        \
  7765. -     char counts[80];                            \
  7766. -                                     \
  7767. -     ASM_GENERATE_INTERNAL_LABEL (counts, "LPBX", 2);            \
  7768. -     cnt_rtx = gen_rtx (SYMBOL_REF, VOIDmode, counts);            \
  7769. -     SYMBOL_REF_FLAG (cnt_rtx) = TRUE;                    \
  7770. -                                     \
  7771. -     if (BLOCKNO)                            \
  7772. -       cnt_rtx = plus_constant (cnt_rtx, (BLOCKNO)*4);            \
  7773. -                                     \
  7774. -     if (flag_pic)                            \
  7775. -       cnt_rtx = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, cnt_rtx);    \
  7776. -                                     \
  7777. -     xops[0] = gen_rtx (MEM, SImode, cnt_rtx);                \
  7778. -     output_asm_insn (AS1(inc%L0,%0), xops);                \
  7779. -   }                                    \
  7780. - while (0)
  7781.   /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
  7782.      the stack pointer does not matter.  The value is tested only in
  7783.      functions that have frame pointers.
  7784. --- 909,914 ----
  7785. ***************
  7786. *** 1146,1180 ****
  7787.      After reload, it makes no difference, since pseudo regs have
  7788.      been eliminated by then.  */
  7789.   
  7790.   
  7791. ! /* Non strict versions, pseudos are ok */
  7792. ! #define REG_OK_FOR_INDEX_NONSTRICT_P(X)                    \
  7793. !   (REGNO (X) < STACK_POINTER_REGNUM                    \
  7794. !    || REGNO (X) >= FIRST_PSEUDO_REGISTER)
  7795.   
  7796. ! #define REG_OK_FOR_BASE_NONSTRICT_P(X)                    \
  7797. !   (REGNO (X) <= STACK_POINTER_REGNUM                    \
  7798. !    || REGNO (X) == ARG_POINTER_REGNUM                    \
  7799.      || REGNO (X) >= FIRST_PSEUDO_REGISTER)
  7800.   
  7801. ! #define REG_OK_FOR_STRREG_NONSTRICT_P(X)                \
  7802.     (REGNO (X) == 4 || REGNO (X) == 5 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
  7803.   
  7804. ! /* Strict versions, hard registers only */
  7805. ! #define REG_OK_FOR_INDEX_STRICT_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
  7806. ! #define REG_OK_FOR_BASE_STRICT_P(X)  REGNO_OK_FOR_BASE_P (REGNO (X))
  7807. ! #define REG_OK_FOR_STRREG_STRICT_P(X)                    \
  7808. !   (REGNO_OK_FOR_DIREG_P (REGNO (X)) || REGNO_OK_FOR_SIREG_P (REGNO (X)))
  7809.   
  7810. ! #ifndef REG_OK_STRICT
  7811. ! #define REG_OK_FOR_INDEX_P(X)  REG_OK_FOR_INDEX_NONSTRICT_P(X)
  7812. ! #define REG_OK_FOR_BASE_P(X)   REG_OK_FOR_BASE_NONSTRICT_P(X)
  7813. ! #define REG_OK_FOR_STRREG_P(X) REG_OK_FOR_STRREG_NONSTRICT_P(X)
  7814.   
  7815. - #else
  7816. - #define REG_OK_FOR_INDEX_P(X)  REG_OK_FOR_INDEX_STRICT_P(X)
  7817. - #define REG_OK_FOR_BASE_P(X)   REG_OK_FOR_BASE_STRICT_P(X)
  7818. - #define REG_OK_FOR_STRREG_P(X) REG_OK_FOR_STRREG_STRICT_P(X)
  7819.   #endif
  7820.   
  7821.   /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
  7822. --- 1072,1107 ----
  7823.      After reload, it makes no difference, since pseudo regs have
  7824.      been eliminated by then.  */
  7825.   
  7826. + #ifndef REG_OK_STRICT
  7827.   
  7828. ! /* Nonzero if X is a hard reg that can be used as an index or if
  7829. !    it is a pseudo reg.  */
  7830.   
  7831. ! #define REG_OK_FOR_INDEX_P(X) \
  7832. !   (REGNO (X) < STACK_POINTER_REGNUM \
  7833.      || REGNO (X) >= FIRST_PSEUDO_REGISTER)
  7834.   
  7835. ! /* Nonzero if X is a hard reg that can be used as a base reg
  7836. !    of if it is a pseudo reg.  */
  7837. !   /* ?wfs */
  7838. ! #define REG_OK_FOR_BASE_P(X) \
  7839. !   (REGNO (X) <= STACK_POINTER_REGNUM \
  7840. !    || REGNO (X) == ARG_POINTER_REGNUM \
  7841. !    || REGNO(X) >= FIRST_PSEUDO_REGISTER)
  7842. ! #define REG_OK_FOR_STRREG_P(X) \
  7843.     (REGNO (X) == 4 || REGNO (X) == 5 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
  7844.   
  7845. ! #else
  7846.   
  7847. ! /* Nonzero if X is a hard reg that can be used as an index.  */
  7848. ! #define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
  7849. ! /* Nonzero if X is a hard reg that can be used as a base reg.  */
  7850. ! #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
  7851. ! #define REG_OK_FOR_STRREG_P(X) \
  7852. !   (REGNO_OK_FOR_DIREG_P (REGNO (X)) || REGNO_OK_FOR_SIREG_P (REGNO (X)))
  7853.   
  7854.   #endif
  7855.   
  7856.   /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
  7857. ***************
  7858. *** 1200,1221 ****
  7859.   
  7860.   #define LEGITIMATE_CONSTANT_P(X) 1
  7861.   
  7862. ! #ifdef REG_OK_STRICT
  7863. ! #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                \
  7864. ! {                                    \
  7865. !   if (legitimate_address_p (MODE, X, 1))                \
  7866. !     goto ADDR;                                \
  7867. ! }
  7868.   
  7869. ! #else
  7870. ! #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                \
  7871.   {                                    \
  7872. !   if (legitimate_address_p (MODE, X, 0))                \
  7873.       goto ADDR;                                \
  7874.   }
  7875.   
  7876. - #endif
  7877.   /* Try machine-dependent ways of modifying an illegitimate address
  7878.      to be legitimate.  If we find one, return the new, valid address.
  7879.      This macro is used in only one place: `memory_address' in explow.c.
  7880. --- 1127,1188 ----
  7881.   
  7882.   #define LEGITIMATE_CONSTANT_P(X) 1
  7883.   
  7884. ! #define GO_IF_INDEXABLE_BASE(X, ADDR)    \
  7885. !  if (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) goto ADDR
  7886.   
  7887. ! #define LEGITIMATE_INDEX_REG_P(X)   \
  7888. !   (GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X))
  7889. ! /* Return 1 if X is an index or an index times a scale.  */
  7890. ! #define LEGITIMATE_INDEX_P(X)   \
  7891. !    (LEGITIMATE_INDEX_REG_P (X)                \
  7892. !     || (GET_CODE (X) == MULT                \
  7893. !     && LEGITIMATE_INDEX_REG_P (XEXP (X, 0))        \
  7894. !     && GET_CODE (XEXP (X, 1)) == CONST_INT        \
  7895. !     && (INTVAL (XEXP (X, 1)) == 2            \
  7896. !         || INTVAL (XEXP (X, 1)) == 4        \
  7897. !         || INTVAL (XEXP (X, 1)) == 8)))
  7898. ! /* Go to ADDR if X is an index term, a base reg, or a sum of those.  */
  7899. ! #define GO_IF_INDEXING(X, ADDR)    \
  7900. ! { if (LEGITIMATE_INDEX_P (X)) goto ADDR;                \
  7901. !   GO_IF_INDEXABLE_BASE (X, ADDR);                    \
  7902. !   if (GET_CODE (X) == PLUS && LEGITIMATE_INDEX_P (XEXP (X, 0)))        \
  7903. !     { GO_IF_INDEXABLE_BASE (XEXP (X, 1), ADDR); }            \
  7904. !   if (GET_CODE (X) == PLUS && LEGITIMATE_INDEX_P (XEXP (X, 1)))        \
  7905. !     { GO_IF_INDEXABLE_BASE (XEXP (X, 0), ADDR); } }
  7906. ! /* We used to allow this, but it isn't ever used.
  7907. !    || ((GET_CODE (X) == POST_DEC || GET_CODE (X) == POST_INC)        \
  7908. !        && REG_P (XEXP (X, 0))                        \
  7909. !        && REG_OK_FOR_STRREG_P (XEXP (X, 0)))                \
  7910. ! */
  7911. ! #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)    \
  7912.   {                                    \
  7913. !   if (CONSTANT_ADDRESS_P (X)                        \
  7914. !       && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (X)))            \
  7915.       goto ADDR;                                \
  7916. +   GO_IF_INDEXING (X, ADDR);                        \
  7917. +   if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1)))        \
  7918. +     {                                    \
  7919. +       rtx x0 = XEXP (X, 0);                        \
  7920. +       if (! flag_pic || ! SYMBOLIC_CONST (XEXP (X, 1)))            \
  7921. +     { GO_IF_INDEXING (x0, ADDR); }                    \
  7922. +       else if (x0 == pic_offset_table_rtx)                \
  7923. +     goto ADDR;                            \
  7924. +       else if (GET_CODE (x0) == PLUS)                    \
  7925. +     {                                \
  7926. +       if (XEXP (x0, 0) == pic_offset_table_rtx)            \
  7927. +         { GO_IF_INDEXABLE_BASE (XEXP (x0, 1), ADDR); }        \
  7928. +       if (XEXP (x0, 1) == pic_offset_table_rtx)            \
  7929. +         { GO_IF_INDEXABLE_BASE (XEXP (x0, 0), ADDR); }        \
  7930. +     }                                \
  7931. +     }                                    \
  7932.   }
  7933.   
  7934.   /* Try machine-dependent ways of modifying an illegitimate address
  7935.      to be legitimate.  If we find one, return the new, valid address.
  7936.      This macro is used in only one place: `memory_address' in explow.c.
  7937. ***************
  7938. *** 1237,1249 ****
  7939.      When -fpic is used, special handling is needed for symbolic references.
  7940.      See comments by legitimize_pic_address in i386.c for details.  */
  7941.   
  7942. ! #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)                \
  7943. ! {                                    \
  7944. !   rtx orig_x = (X);                            \
  7945. !   (X) = legitimize_address (X, OLDX, MODE);                \
  7946. !   if (memory_address_p (MODE, X))                    \
  7947. !     goto WIN;                                \
  7948. ! }
  7949.   
  7950.   /* Nonzero if the constant value X is a legitimate general operand
  7951.      when generating PIC code.  It is given that flag_pic is on and 
  7952. --- 1204,1244 ----
  7953.      When -fpic is used, special handling is needed for symbolic references.
  7954.      See comments by legitimize_pic_address in i386.c for details.  */
  7955.   
  7956. ! #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)   \
  7957. ! { extern rtx legitimize_pic_address ();                    \
  7958. !   int ch = (X) != (OLDX);                        \
  7959. !   if (flag_pic && SYMBOLIC_CONST (X))                    \
  7960. !     {                                    \
  7961. !       (X) = legitimize_pic_address (X, 0);                \
  7962. !       if (memory_address_p (MODE, X))                    \
  7963. !     goto WIN;                            \
  7964. !     }                                    \
  7965. !   if (GET_CODE (X) == PLUS)                        \
  7966. !     { if (GET_CODE (XEXP (X, 0)) == MULT)                \
  7967. !     ch = 1, XEXP (X, 0) = force_operand (XEXP (X, 0), 0);        \
  7968. !       if (GET_CODE (XEXP (X, 1)) == MULT)                \
  7969. !     ch = 1, XEXP (X, 1) = force_operand (XEXP (X, 1), 0);        \
  7970. !       if (ch && GET_CODE (XEXP (X, 1)) == REG                \
  7971. !       && GET_CODE (XEXP (X, 0)) == REG)                \
  7972. !     goto WIN;                            \
  7973. !       if (flag_pic && SYMBOLIC_CONST (XEXP (X, 1)))            \
  7974. !         ch = 1, (X) = legitimize_pic_address (X, 0);            \
  7975. !       if (ch) { GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN); }        \
  7976. !       if (GET_CODE (XEXP (X, 0)) == REG)                                \
  7977. !     { register rtx temp = gen_reg_rtx (Pmode);            \
  7978. !       register rtx val = force_operand (XEXP (X, 1), temp);        \
  7979. !       if (val != temp) emit_move_insn (temp, val);            \
  7980. !       XEXP (X, 1) = temp;                        \
  7981. !       goto WIN; }                            \
  7982. !       else if (GET_CODE (XEXP (X, 1)) == REG)                \
  7983. !     { register rtx temp = gen_reg_rtx (Pmode);            \
  7984. !       register rtx val = force_operand (XEXP (X, 0), temp);        \
  7985. !       if (val != temp) emit_move_insn (temp, val);            \
  7986. !       XEXP (X, 0) = temp;                        \
  7987. !       goto WIN; }}}
  7988. ! /* intel1 */
  7989. ! #define REWRITE_ADDRESS(x) rewrite_address(x)
  7990.   
  7991.   /* Nonzero if the constant value X is a legitimate general operand
  7992.      when generating PIC code.  It is given that flag_pic is on and 
  7993. ***************
  7994. *** 1381,1386 ****
  7995. --- 1376,1385 ----
  7996.   /* Nonzero if access to memory by bytes is slow and undesirable.  */
  7997.   #define SLOW_BYTE_ACCESS 0
  7998.   
  7999. + /* intel1 */
  8000. + /* Nonzero if access to memory by shorts is slow and undesirable.  */
  8001. + #define SLOW_SHORT_ACCESS 1
  8002.   /* Define if shifts truncate the shift count
  8003.      which implies one can omit a sign-extension or zero-extension
  8004.      of a shift count.  */
  8005. ***************
  8006. *** 1512,1517 ****
  8007. --- 1511,1517 ----
  8008.      stored from the compare operation.  Note that we can't use "rtx" here
  8009.      since it hasn't been defined!  */
  8010.   
  8011. + extern struct rtx_def *i386_compare_op0, *i386_compare_op1;
  8012.   extern struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
  8013.   
  8014.   /* Tell final.c how to eliminate redundant test instructions.  */
  8015. ***************
  8016. *** 1519,1524 ****
  8017. --- 1519,1528 ----
  8018.   /* Here we define machine-dependent flags and fields in cc_status
  8019.      (see `conditions.h').  */
  8020.   
  8021. + /* intel1 Set if the cc value is was actually from the 80387 and
  8022. +    we are testing eax directly (i.e. no sahf) */
  8023. + #define CC_TEST_AX 020000
  8024.   /* Set if the cc value is actually in the 80387, so a floating point
  8025.      conditional branch must be output.  */
  8026.   #define CC_IN_80387 04000
  8027. ***************
  8028. *** 1816,1827 ****
  8029.        { fputs ("argp", FILE); break; }        \
  8030.          if (STACK_TOP_P (X))                \
  8031.        { fputs ("st(0)", FILE); break; }        \
  8032. -        if (FP_REG_P (X))                \
  8033. -      { fputs (hi_name[REGNO(X)], FILE); break; }    \
  8034.          switch (GET_MODE_SIZE (GET_MODE (X)))        \
  8035.        {                        \
  8036. !      default:                    \
  8037. !        fputs ("e", FILE);                \
  8038.        case 2:                    \
  8039.          fputs (hi_name[REGNO (X)], FILE);        \
  8040.          break;                    \
  8041. --- 1820,1831 ----
  8042.        { fputs ("argp", FILE); break; }        \
  8043.          if (STACK_TOP_P (X))                \
  8044.        { fputs ("st(0)", FILE); break; }        \
  8045.          switch (GET_MODE_SIZE (GET_MODE (X)))        \
  8046.        {                        \
  8047. !      case 12:                    \
  8048. !      case 8:                    \
  8049. !      case 4:                    \
  8050. !        if (! FP_REG_P (X)) fputs ("e", FILE);    \
  8051.        case 2:                    \
  8052.          fputs (hi_name[REGNO (X)], FILE);        \
  8053.          break;                    \
  8054. ***************
  8055. *** 1857,1865 ****
  8056.   #define RET return ""
  8057.   #define AT_SP(mode) (gen_rtx (MEM, (mode), stack_pointer_rtx))
  8058.   
  8059. - /* Functions in i386.c */
  8060. - extern void override_options ();
  8061. - extern void order_regs_for_local_alloc ();
  8062.   extern int i386_valid_decl_attribute_p ();
  8063.   extern int i386_valid_type_attribute_p ();
  8064.   extern int i386_return_pops_args ();
  8065. --- 1861,1866 ----
  8066. ***************
  8067. *** 1868,1909 ****
  8068.   extern void function_arg_advance ();
  8069.   extern struct rtx_def *function_arg ();
  8070.   extern int function_arg_partial_nregs ();
  8071. - extern void output_op_from_reg ();
  8072. - extern void output_to_reg ();
  8073. - extern char *singlemove_string ();
  8074. - extern char *output_move_double ();
  8075. - extern char *output_move_memory ();
  8076. - extern char *output_move_pushmem ();
  8077. - extern int standard_80387_constant_p ();
  8078. - extern char *output_move_const_single ();
  8079. - extern int symbolic_operand ();
  8080. - extern int call_insn_operand ();
  8081. - extern int expander_call_insn_operand ();
  8082. - extern int symbolic_reference_mentioned_p ();
  8083. - extern void emit_pic_move ();
  8084. - extern void function_prologue ();
  8085. - extern int simple_386_epilogue ();
  8086. - extern void function_epilogue ();
  8087. - extern int legitimate_address_p ();
  8088. - extern struct rtx_def *legitimize_pic_address ();
  8089. - extern struct rtx_def *legitimize_address ();
  8090. - extern void print_operand ();
  8091. - extern void print_operand_address ();
  8092. - extern void notice_update_cc ();
  8093. - extern void split_di ();
  8094. - extern int binary_387_op ();
  8095. - extern int shift_op ();
  8096. - extern int VOIDmode_compare_op ();
  8097. - extern char *output_387_binary_op ();
  8098. - extern char *output_fix_trunc ();
  8099. - extern char *output_float_compare ();
  8100. - extern char *output_fp_cc0_set ();
  8101. - extern void save_386_machine_status ();
  8102. - extern void restore_386_machine_status ();
  8103. - extern void clear_386_stack_locals ();
  8104. - extern struct rtx_def *assign_386_stack_local ();
  8105.   
  8106. ! /* Variables in i386.c */
  8107.   extern char *i386_reg_alloc_order;        /* register allocation order */
  8108.   extern char *i386_regparm_string;        /* # registers to use to pass args */
  8109.   extern char *i386_align_loops_string;        /* power of two alignment for loops */
  8110. --- 1869,1876 ----
  8111.   extern void function_arg_advance ();
  8112.   extern struct rtx_def *function_arg ();
  8113.   extern int function_arg_partial_nregs ();
  8114.   
  8115. !   /* Variables in i386.c */
  8116.   extern char *i386_reg_alloc_order;        /* register allocation order */
  8117.   extern char *i386_regparm_string;        /* # registers to use to pass args */
  8118.   extern char *i386_align_loops_string;        /* power of two alignment for loops */
  8119. ***************
  8120. *** 1913,1932 ****
  8121.   extern int i386_align_loops;            /* power of two alignment for loops */
  8122.   extern int i386_align_jumps;            /* power of two alignment for non-loop jumps */
  8123.   extern int i386_align_funcs;            /* power of two alignment for functions */
  8124. ! extern char *hi_reg_name[];            /* names for 16 bit regs */
  8125. ! extern char *qi_reg_name[];            /* names for 8 bit regs (low) */
  8126. ! extern char *qi_high_reg_name[];        /* names for 8 bit regs (high) */
  8127. ! extern enum reg_class regclass_map[];        /* smalled class containing REGNO */
  8128. ! extern struct rtx_def *i386_compare_op0;    /* operand 0 for comparisons */
  8129. ! extern struct rtx_def *i386_compare_op1;    /* operand 1 for comparisons */
  8130. ! /* External variables used */
  8131. ! extern int optimize;            /* optimization level */
  8132. ! extern int obey_regdecls;        /* TRUE if stupid register allocation */
  8133. ! /* External functions used */
  8134. ! extern struct rtx_def *force_operand ();
  8135.   /*
  8136.   Local variables:
  8137.   version-control: t
  8138. --- 1880,1888 ----
  8139.   extern int i386_align_loops;            /* power of two alignment for loops */
  8140.   extern int i386_align_jumps;            /* power of two alignment for non-loop jumps */
  8141.   extern int i386_align_funcs;            /* power of two alignment for functions */
  8142. ! /*extern char *hi_reg_name[];            /* names for 16 bit regs */
  8143. ! /*extern char *qi_reg_name[];            /* names for 8 bit regs (low) */
  8144. ! /*extern char *qi_high_reg_name[];        /* names for 8 bit regs (high) */
  8145.   /*
  8146.   Local variables:
  8147.   version-control: t
  8148. diff -rNci gcc-2.7.2/config/i386/i386.md gcc-2.7.2p/config/i386/i386.md
  8149. *** gcc-2.7.2/config/i386/i386.md    Mon Aug 21 17:27:58 1995
  8150. --- gcc-2.7.2p/config/i386/i386.md    Tue Jan 23 09:35:00 1996
  8151. ***************
  8152. *** 2,7 ****
  8153. --- 2,10 ----
  8154.   ;; Copyright (C) 1988, 1994, 1995 Free Software Foundation, Inc.
  8155.   ;; Mostly by William Schelter.
  8156.   
  8157. + ;; Pentium cpu support and other enhancements by Tevi Devor Intel Corp.
  8158. + ;; (tevi@iil.intel.com).
  8159.   ;; This file is part of GNU CC.
  8160.   
  8161.   ;; GNU CC is free software; you can redistribute it and/or modify
  8162. ***************
  8163. *** 72,77 ****
  8164. --- 75,110 ----
  8165.   ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
  8166.   ;; after the tstM or cmp) will actually emit the tstM or cmpM.
  8167.   
  8168. + ;intel1
  8169. + (define_attr "type" "fld,integer,fpop,fpdiv"
  8170. +   (const_string "integer"))
  8171. + ;; Functional units intel1
  8172. + (define_function_unit "fp" 1 0
  8173. +  (and (eq_attr "type" "fpop") 
  8174. +       (ne (symbol_ref "x86_cpu") (symbol_ref "PROCESSOR_PENTIUM")))
  8175. +  5 5)
  8176. + (define_function_unit "fp" 1 0
  8177. +  (and (eq_attr "type" "fpop") 
  8178. +       (eq (symbol_ref "x86_cpu") (symbol_ref "PROCESSOR_PENTIUM")))
  8179. +  3 0)
  8180. + (define_function_unit "fp" 1 0
  8181. +  (eq_attr "type" "fpdiv") 
  8182. +  10 10)
  8183. + (define_function_unit "fp" 1 0
  8184. +  (eq_attr "type" "fld") 
  8185. +  1 0)
  8186. + (define_function_unit "integer" 1 0
  8187. +  (and (eq_attr "type" "integer") 
  8188. +       (ne (symbol_ref "x86_cpu") (symbol_ref "PROCESSOR_386")))
  8189. +  2 0)
  8190.   (define_insn "tstsi_1"
  8191.     [(set (cc0)
  8192.       (match_operand:SI 0 "nonimmediate_operand" "rm"))]
  8193. ***************
  8194. *** 144,247 ****
  8195.     DONE;
  8196.   }")
  8197.   
  8198. ! (define_insn "tstsf_cc"
  8199. !   [(set (cc0)
  8200. !     (match_operand:SF 0 "register_operand" "f"))
  8201. !    (clobber (match_scratch:HI 1 "=a"))]
  8202. !   "TARGET_80387 && ! TARGET_IEEE_FP"
  8203. !   "*
  8204. ! {
  8205. !   if (! STACK_TOP_P (operands[0]))
  8206. !     abort ();
  8207. !   output_asm_insn (\"ftst\", operands);
  8208. !   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  8209. !     output_asm_insn (AS1 (fstp,%y0), operands);
  8210. !   return output_fp_cc0_set (insn);
  8211. ! }")
  8212. ! ;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
  8213. ! ;; isn't IEEE compliant.
  8214. ! (define_expand "tstsf"
  8215. !   [(parallel [(set (cc0)
  8216. !            (match_operand:SF 0 "register_operand" ""))
  8217. !           (clobber (match_scratch:HI 1 ""))])]
  8218. !   "TARGET_80387 && ! TARGET_IEEE_FP"
  8219. !   "
  8220. ! {
  8221. !   i386_compare_gen = gen_tstsf_cc;
  8222. !   i386_compare_op0 = operands[0];
  8223. !   DONE;
  8224. ! }")
  8225. ! (define_insn "tstdf_cc"
  8226. !   [(set (cc0)
  8227. !     (match_operand:DF 0 "register_operand" "f"))
  8228. !    (clobber (match_scratch:HI 1 "=a"))]
  8229. !   "TARGET_80387 && ! TARGET_IEEE_FP"
  8230. !   "*
  8231. ! {
  8232. !   if (! STACK_TOP_P (operands[0]))
  8233. !     abort ();
  8234. !   output_asm_insn (\"ftst\", operands);
  8235. !   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  8236. !     output_asm_insn (AS1 (fstp,%y0), operands);
  8237. !   return output_fp_cc0_set (insn);
  8238. ! }")
  8239. ! ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
  8240. ! ;; isn't IEEE compliant.
  8241. ! (define_expand "tstdf"
  8242. !   [(parallel [(set (cc0)
  8243. !            (match_operand:DF 0 "register_operand" ""))
  8244. !           (clobber (match_scratch:HI 1 ""))])]
  8245. !   "TARGET_80387 && ! TARGET_IEEE_FP"
  8246. !   "
  8247. ! {
  8248. !   i386_compare_gen = gen_tstdf_cc;
  8249. !   i386_compare_op0 = operands[0];
  8250. !   DONE;
  8251. ! }")
  8252. ! (define_insn "tstxf_cc"
  8253. !   [(set (cc0)
  8254. !     (match_operand:XF 0 "register_operand" "f"))
  8255. !    (clobber (match_scratch:HI 1 "=a"))]
  8256. !   "TARGET_80387 && ! TARGET_IEEE_FP"
  8257. !   "*
  8258. ! {
  8259. !   if (! STACK_TOP_P (operands[0]))
  8260. !     abort ();
  8261. !   output_asm_insn (\"ftst\", operands);
  8262. !   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  8263. !     output_asm_insn (AS1 (fstp,%y0), operands);
  8264. !   return output_fp_cc0_set (insn);
  8265. ! }")
  8266. ! ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
  8267. ! ;; isn't IEEE compliant.
  8268. ! (define_expand "tstxf"
  8269. !   [(parallel [(set (cc0)
  8270. !            (match_operand:XF 0 "register_operand" ""))
  8271. !           (clobber (match_scratch:HI 1 ""))])]
  8272. !   "TARGET_80387 && ! TARGET_IEEE_FP"
  8273. !   "
  8274. ! {
  8275. !   i386_compare_gen = gen_tstxf_cc;
  8276. !   i386_compare_op0 = operands[0];
  8277. !   DONE;
  8278. ! }")
  8279.   
  8280.   ;;- compare instructions.  See comments above tstM patterns about
  8281.   ;;  expansion of these insns.
  8282. --- 177,281 ----
  8283.     DONE;
  8284.   }")
  8285.   
  8286. ! ;; intel1
  8287. ! ;;(define_insn "tstsf_cc"
  8288. ! ;;  [(set (cc0)
  8289. ! ;;    (match_operand:SF 0 "register_operand" "f"))
  8290. ! ;;   (clobber (match_scratch:HI 1 "=a"))]
  8291. ! ;;  "TARGET_80387 && ! TARGET_IEEE_FP"
  8292. ! ;;  "*
  8293. ! ;;{
  8294. ! ;;  if (! STACK_TOP_P (operands[0]))
  8295. ! ;;    abort ();
  8296. ! ;;
  8297. ! ;;  output_asm_insn (\"ftst\", operands);
  8298. ! ;;
  8299. ! ;;  if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  8300. ! ;;    output_asm_insn (AS1 (fstp,%y0), operands);
  8301. ! ;;
  8302. ! ;;  return (char *) output_fp_cc0_set (insn);
  8303. ! ;;}")
  8304. ! ;;
  8305. ! ;;;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
  8306. ! ;;;; isn't IEEE compliant.
  8307. ! ;;
  8308. ! ;;(define_expand "tstsf"
  8309. ! ;;  [(parallel [(set (cc0)
  8310. ! ;;           (match_operand:SF 0 "register_operand" ""))
  8311. ! ;;          (clobber (match_scratch:HI 1 ""))])]
  8312. ! ;;  "TARGET_80387 && ! TARGET_IEEE_FP"
  8313. ! ;;  "
  8314. ! ;;{
  8315. ! ;;  i386_compare_gen = gen_tstsf_cc;
  8316. ! ;;  i386_compare_op0 = operands[0];
  8317. ! ;;  DONE;
  8318. ! ;;}")
  8319. ! ;;
  8320. ! ;;(define_insn "tstdf_cc"
  8321. ! ;;  [(set (cc0)
  8322. ! ;;    (match_operand:DF 0 "register_operand" "f"))
  8323. ! ;;   (clobber (match_scratch:HI 1 "=a"))]
  8324. ! ;;  "TARGET_80387 && ! TARGET_IEEE_FP"
  8325. ! ;;  "*
  8326. ! ;;{
  8327. ! ;;  if (! STACK_TOP_P (operands[0]))
  8328. ! ;;    abort ();
  8329. ! ;;
  8330. ! ;;  output_asm_insn (\"ftst\", operands);
  8331. ! ;;
  8332. ! ;;  if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  8333. ! ;;    output_asm_insn (AS1 (fstp,%y0), operands);
  8334. ! ;;
  8335. ! ;;  return (char *) output_fp_cc0_set (insn);
  8336. ! ;;}")
  8337. ! ;;
  8338. ! ;;;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
  8339. ! ;;;; isn't IEEE compliant.
  8340. ! ;;
  8341. ! ;;(define_expand "tstdf"
  8342. ! ;;  [(parallel [(set (cc0)
  8343. ! ;;           (match_operand:DF 0 "register_operand" ""))
  8344. ! ;;          (clobber (match_scratch:HI 1 ""))])]
  8345. ! ;;  "TARGET_80387 && ! TARGET_IEEE_FP"
  8346. ! ;;  "
  8347. ! ;;{
  8348. ! ;;  i386_compare_gen = gen_tstdf_cc;
  8349. ! ;;  i386_compare_op0 = operands[0];
  8350. ! ;;  DONE;
  8351. ! ;;}")
  8352. ! ;;(define_insn "tstxf_cc"
  8353. ! ;;  [(set (cc0)
  8354. ! ;;      (match_operand:XF 0 "register_operand" "f"))
  8355. ! ;;   (clobber (match_scratch:HI 1 "=a"))]
  8356. ! ;;  "TARGET_80387 && ! TARGET_IEEE_FP"
  8357. ! ;;  "*
  8358. ! ;;{
  8359. ! ;;  if (! STACK_TOP_P (operands[0]))
  8360. ! ;;    abort ();
  8361. ! ;;
  8362. ! ;;  output_asm_insn (\"ftst\", operands);
  8363. ! ;;
  8364. ! ;;  if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  8365. ! ;;    output_asm_insn (AS1 (fstp,%y0), operands);
  8366. ! ;;
  8367. ! ;;  return (char *) output_fp_cc0_set (insn);
  8368. ! ;;}")
  8369. ! ;;
  8370. ! ;;;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
  8371. ! ;;;; isn't IEEE compliant.
  8372. ! ;;
  8373. ! ;;(define_expand "tstxf"
  8374. ! ;;  [(parallel [(set (cc0)
  8375. ! ;;                 (match_operand:XF 0 "register_operand" ""))
  8376. ! ;;            (clobber (match_scratch:HI 1 ""))])]
  8377. ! ;;  "TARGET_80387 && ! TARGET_IEEE_FP"
  8378. ! ;;  "
  8379. ! ;;{
  8380. ! ;;  i386_compare_gen = gen_tstxf_cc;
  8381. ! ;;  i386_compare_op0 = operands[0];
  8382. ! ;;  DONE;
  8383. ! ;;}")
  8384.   
  8385.   ;;- compare instructions.  See comments above tstM patterns about
  8386.   ;;  expansion of these insns.
  8387. ***************
  8388. *** 343,397 ****
  8389.   ;; SFmode, there is the normal insn, and an insn where the second operand
  8390.   ;; is converted to the desired mode.
  8391.   
  8392.   (define_insn ""
  8393.     [(set (cc0)
  8394.       (match_operator 2 "VOIDmode_compare_op"
  8395. !             [(match_operand:XF 0 "nonimmediate_operand" "f")
  8396. !              (match_operand:XF 1 "nonimmediate_operand" "f")]))
  8397.      (clobber (match_scratch:HI 3 "=a"))]
  8398.     "TARGET_80387
  8399.      && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  8400. !   "* return output_float_compare (insn, operands);")
  8401.   
  8402.   (define_insn ""
  8403.     [(set (cc0)
  8404.       (match_operator 2 "VOIDmode_compare_op"
  8405.               [(match_operand:XF 0 "register_operand" "f")
  8406.                (float:XF
  8407. !               (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  8408.      (clobber (match_scratch:HI 3 "=a"))]
  8409.     "TARGET_80387"
  8410. !   "* return output_float_compare (insn, operands);")
  8411.   
  8412.   (define_insn ""
  8413.     [(set (cc0)
  8414.       (match_operator 2 "VOIDmode_compare_op"
  8415.               [(float:XF
  8416. !               (match_operand:SI 0 "nonimmediate_operand" "rm"))
  8417.                (match_operand:XF 1 "register_operand" "f")]))
  8418.      (clobber (match_scratch:HI 3 "=a"))]
  8419.     "TARGET_80387"
  8420. !   "* return output_float_compare (insn, operands);")
  8421.   
  8422.   (define_insn ""
  8423.     [(set (cc0)
  8424.       (match_operator 2 "VOIDmode_compare_op"
  8425.               [(match_operand:XF 0 "register_operand" "f")
  8426.                (float_extend:XF
  8427. !               (match_operand:DF 1 "nonimmediate_operand" "fm"))]))
  8428.      (clobber (match_scratch:HI 3 "=a"))]
  8429.     "TARGET_80387"
  8430. !   "* return output_float_compare (insn, operands);")
  8431.   
  8432.   (define_insn ""
  8433.     [(set (cc0)
  8434.       (match_operator 2 "VOIDmode_compare_op"
  8435.               [(match_operand:XF 0 "register_operand" "f")
  8436.                (float_extend:XF
  8437. !               (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
  8438.      (clobber (match_scratch:HI 3 "=a"))]
  8439.     "TARGET_80387"
  8440. !   "* return output_float_compare (insn, operands);")
  8441.   
  8442.   (define_insn ""
  8443.     [(set (cc0)
  8444. --- 377,432 ----
  8445.   ;; SFmode, there is the normal insn, and an insn where the second operand
  8446.   ;; is converted to the desired mode.
  8447.   
  8448. + ;;intel1 operand 1 and 2 changed from nonimmediate_operand to general_operand
  8449.   (define_insn ""
  8450.     [(set (cc0)
  8451.       (match_operator 2 "VOIDmode_compare_op"
  8452. !             [(match_operand:XF 0 "general_operand" "f")
  8453. !              (match_operand:XF 1 "general_operand" "f")]))
  8454.      (clobber (match_scratch:HI 3 "=a"))]
  8455.     "TARGET_80387
  8456.      && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  8457. !   "* return (char *) output_float_compare (insn, operands);")
  8458.   
  8459.   (define_insn ""
  8460.     [(set (cc0)
  8461.       (match_operator 2 "VOIDmode_compare_op"
  8462.               [(match_operand:XF 0 "register_operand" "f")
  8463.                (float:XF
  8464. !               (match_operand:SI 1 "general_operand" "rm"))]))
  8465.      (clobber (match_scratch:HI 3 "=a"))]
  8466.     "TARGET_80387"
  8467. !   "* return (char *) output_float_compare (insn, operands);")
  8468.   
  8469.   (define_insn ""
  8470.     [(set (cc0)
  8471.       (match_operator 2 "VOIDmode_compare_op"
  8472.               [(float:XF
  8473. !               (match_operand:SI 0 "general_operand" "rm"))
  8474.                (match_operand:XF 1 "register_operand" "f")]))
  8475.      (clobber (match_scratch:HI 3 "=a"))]
  8476.     "TARGET_80387"
  8477. !   "* return (char *) output_float_compare (insn, operands);")
  8478.   
  8479.   (define_insn ""
  8480.     [(set (cc0)
  8481.       (match_operator 2 "VOIDmode_compare_op"
  8482.               [(match_operand:XF 0 "register_operand" "f")
  8483.                (float_extend:XF
  8484. !               (match_operand:DF 1 "general_operand" "fm"))]))
  8485.      (clobber (match_scratch:HI 3 "=a"))]
  8486.     "TARGET_80387"
  8487. !   "* return (char *) output_float_compare (insn, operands);")
  8488.   
  8489.   (define_insn ""
  8490.     [(set (cc0)
  8491.       (match_operator 2 "VOIDmode_compare_op"
  8492.               [(match_operand:XF 0 "register_operand" "f")
  8493.                (float_extend:XF
  8494. !               (match_operand:SF 1 "general_operand" "fm"))]))
  8495.      (clobber (match_scratch:HI 3 "=a"))]
  8496.     "TARGET_80387"
  8497. !   "* return (char *) output_float_compare (insn, operands);")
  8498.   
  8499.   (define_insn ""
  8500.     [(set (cc0)
  8501. ***************
  8502. *** 399,415 ****
  8503.               (match_operand:XF 1 "register_operand" "f")))
  8504.      (clobber (match_scratch:HI 2 "=a"))]
  8505.     "TARGET_80387"
  8506. !   "* return output_float_compare (insn, operands);")
  8507.   
  8508.   (define_insn ""
  8509.     [(set (cc0)
  8510.       (match_operator 2 "VOIDmode_compare_op"
  8511. !             [(match_operand:DF 0 "nonimmediate_operand" "f,fm")
  8512. !              (match_operand:DF 1 "nonimmediate_operand" "fm,f")]))
  8513.      (clobber (match_scratch:HI 3 "=a,a"))]
  8514.     "TARGET_80387
  8515.      && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  8516. !   "* return output_float_compare (insn, operands);")
  8517.   
  8518.   (define_insn ""
  8519.     [(set (cc0)
  8520. --- 434,450 ----
  8521.               (match_operand:XF 1 "register_operand" "f")))
  8522.      (clobber (match_scratch:HI 2 "=a"))]
  8523.     "TARGET_80387"
  8524. !   "* return (char *) output_float_compare (insn, operands);")
  8525.   
  8526.   (define_insn ""
  8527.     [(set (cc0)
  8528.       (match_operator 2 "VOIDmode_compare_op"
  8529. !             [(match_operand:DF 0 "general_operand" "f,fm")
  8530. !              (match_operand:DF 1 "general_operand" "fm,f")]))
  8531.      (clobber (match_scratch:HI 3 "=a,a"))]
  8532.     "TARGET_80387
  8533.      && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  8534. !   "* return (char *) output_float_compare (insn, operands);")
  8535.   
  8536.   (define_insn ""
  8537.     [(set (cc0)
  8538. ***************
  8539. *** 419,425 ****
  8540.                 (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  8541.      (clobber (match_scratch:HI 3 "=a"))]
  8542.     "TARGET_80387"
  8543. !   "* return output_float_compare (insn, operands);")
  8544.   
  8545.   (define_insn ""
  8546.     [(set (cc0)
  8547. --- 454,460 ----
  8548.                 (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  8549.      (clobber (match_scratch:HI 3 "=a"))]
  8550.     "TARGET_80387"
  8551. !   "* return (char *) output_float_compare (insn, operands);")
  8552.   
  8553.   (define_insn ""
  8554.     [(set (cc0)
  8555. ***************
  8556. *** 429,435 ****
  8557.                (match_operand:DF 1 "register_operand" "f")]))
  8558.      (clobber (match_scratch:HI 3 "=a"))]
  8559.     "TARGET_80387"
  8560. !   "* return output_float_compare (insn, operands);")
  8561.   
  8562.   (define_insn ""
  8563.     [(set (cc0)
  8564. --- 464,470 ----
  8565.                (match_operand:DF 1 "register_operand" "f")]))
  8566.      (clobber (match_scratch:HI 3 "=a"))]
  8567.     "TARGET_80387"
  8568. !   "* return (char *) output_float_compare (insn, operands);")
  8569.   
  8570.   (define_insn ""
  8571.     [(set (cc0)
  8572. ***************
  8573. *** 439,445 ****
  8574.                 (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
  8575.      (clobber (match_scratch:HI 3 "=a"))]
  8576.     "TARGET_80387"
  8577. !   "* return output_float_compare (insn, operands);")
  8578.   
  8579.   (define_insn ""
  8580.     [(set (cc0)
  8581. --- 474,480 ----
  8582.                 (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
  8583.      (clobber (match_scratch:HI 3 "=a"))]
  8584.     "TARGET_80387"
  8585. !   "* return (char *) output_float_compare (insn, operands);")
  8586.   
  8587.   (define_insn ""
  8588.     [(set (cc0)
  8589. ***************
  8590. *** 449,455 ****
  8591.                (match_operand:DF 1 "register_operand" "f")]))
  8592.      (clobber (match_scratch:HI 3 "=a"))]
  8593.     "TARGET_80387"
  8594. !   "* return output_float_compare (insn, operands);")
  8595.   
  8596.   (define_insn ""
  8597.     [(set (cc0)
  8598. --- 484,501 ----
  8599.                (match_operand:DF 1 "register_operand" "f")]))
  8600.      (clobber (match_scratch:HI 3 "=a"))]
  8601.     "TARGET_80387"
  8602. !   "* return (char *) output_float_compare (insn, operands);")
  8603. ! ;;intel1 
  8604. ! (define_insn ""
  8605. !   [(set (cc0)
  8606. !     (match_operator 2 "VOIDmode_compare_op"
  8607. !             [(float_extend:DF
  8608. !               (match_operand:SF 0 "register_operand" "f"))
  8609. !              (match_operand:DF 1 "general_operand" "fm")]))
  8610. !    (clobber (match_scratch:HI 3 "=a"))]
  8611. !   "TARGET_80387"
  8612. !   "* return (char *) output_float_compare (insn, operands);")
  8613.   
  8614.   (define_insn ""
  8615.     [(set (cc0)
  8616. ***************
  8617. *** 457,463 ****
  8618.               (match_operand:DF 1 "register_operand" "f")))
  8619.      (clobber (match_scratch:HI 2 "=a"))]
  8620.     "TARGET_80387"
  8621. !   "* return output_float_compare (insn, operands);")
  8622.   
  8623.   ;; These two insns will never be generated by combine due to the mode of
  8624.   ;; the COMPARE.
  8625. --- 503,509 ----
  8626.               (match_operand:DF 1 "register_operand" "f")))
  8627.      (clobber (match_scratch:HI 2 "=a"))]
  8628.     "TARGET_80387"
  8629. !   "* return (char *) output_float_compare (insn, operands);")
  8630.   
  8631.   ;; These two insns will never be generated by combine due to the mode of
  8632.   ;; the COMPARE.
  8633. ***************
  8634. *** 468,474 ****
  8635.   ;             (match_operand:SF 1 "register_operand" "f"))))
  8636.   ;   (clobber (match_scratch:HI 2 "=a"))]
  8637.   ;  "TARGET_80387"
  8638. ! ;  "* return output_float_compare (insn, operands);")
  8639.   ;
  8640.   ;(define_insn ""
  8641.   ;  [(set (cc0)
  8642. --- 514,520 ----
  8643.   ;             (match_operand:SF 1 "register_operand" "f"))))
  8644.   ;   (clobber (match_scratch:HI 2 "=a"))]
  8645.   ;  "TARGET_80387"
  8646. ! ;  "* return (char *) output_float_compare (insn, operands);")
  8647.   ;
  8648.   ;(define_insn ""
  8649.   ;  [(set (cc0)
  8650. ***************
  8651. *** 477,493 ****
  8652.   ;            (match_operand:DF 1 "register_operand" "f")))
  8653.   ;   (clobber (match_scratch:HI 2 "=a"))]
  8654.   ;  "TARGET_80387"
  8655. ! ;  "* return output_float_compare (insn, operands);")
  8656.   
  8657.   (define_insn "cmpsf_cc_1"
  8658.     [(set (cc0)
  8659.       (match_operator 2 "VOIDmode_compare_op"
  8660.               [(match_operand:SF 0 "nonimmediate_operand" "f,fm")
  8661. !              (match_operand:SF 1 "nonimmediate_operand" "fm,f")]))
  8662.      (clobber (match_scratch:HI 3 "=a,a"))]
  8663.     "TARGET_80387
  8664.      && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  8665. !   "* return output_float_compare (insn, operands);")
  8666.   
  8667.   (define_insn ""
  8668.     [(set (cc0)
  8669. --- 523,540 ----
  8670.   ;            (match_operand:DF 1 "register_operand" "f")))
  8671.   ;   (clobber (match_scratch:HI 2 "=a"))]
  8672.   ;  "TARGET_80387"
  8673. ! ;  "* return (char *) output_float_compare (insn, operands);")
  8674.   
  8675. + ;;intel1 operand 1 changed from nonimmediate_operand to general_operand
  8676.   (define_insn "cmpsf_cc_1"
  8677.     [(set (cc0)
  8678.       (match_operator 2 "VOIDmode_compare_op"
  8679.               [(match_operand:SF 0 "nonimmediate_operand" "f,fm")
  8680. !              (match_operand:SF 1 "general_operand" "fm,f")]))
  8681.      (clobber (match_scratch:HI 3 "=a,a"))]
  8682.     "TARGET_80387
  8683.      && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  8684. !   "* return (char *) output_float_compare (insn, operands);")
  8685.   
  8686.   (define_insn ""
  8687.     [(set (cc0)
  8688. ***************
  8689. *** 497,503 ****
  8690.                 (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  8691.      (clobber (match_scratch:HI 3 "=a"))]
  8692.     "TARGET_80387"
  8693. !   "* return output_float_compare (insn, operands);")
  8694.   
  8695.   (define_insn ""
  8696.     [(set (cc0)
  8697. --- 544,550 ----
  8698.                 (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  8699.      (clobber (match_scratch:HI 3 "=a"))]
  8700.     "TARGET_80387"
  8701. !   "* return (char *) output_float_compare (insn, operands);")
  8702.   
  8703.   (define_insn ""
  8704.     [(set (cc0)
  8705. ***************
  8706. *** 507,513 ****
  8707.                (match_operand:SF 1 "register_operand" "f")]))
  8708.      (clobber (match_scratch:HI 3 "=a"))]
  8709.     "TARGET_80387"
  8710. !   "* return output_float_compare (insn, operands);")
  8711.   
  8712.   (define_insn ""
  8713.     [(set (cc0)
  8714. --- 554,560 ----
  8715.                (match_operand:SF 1 "register_operand" "f")]))
  8716.      (clobber (match_scratch:HI 3 "=a"))]
  8717.     "TARGET_80387"
  8718. !   "* return (char *) output_float_compare (insn, operands);")
  8719.   
  8720.   (define_insn ""
  8721.     [(set (cc0)
  8722. ***************
  8723. *** 515,526 ****
  8724.               (match_operand:SF 1 "register_operand" "f")))
  8725.      (clobber (match_scratch:HI 2 "=a"))]
  8726.     "TARGET_80387"
  8727. !   "* return output_float_compare (insn, operands);")
  8728.   
  8729.   (define_expand "cmpxf"
  8730.     [(set (cc0)
  8731. !     (compare (match_operand:XF 0 "register_operand" "")
  8732. !          (match_operand:XF 1 "nonimmediate_operand" "")))]
  8733.     "TARGET_80387"
  8734.     "
  8735.   {
  8736. --- 562,573 ----
  8737.               (match_operand:SF 1 "register_operand" "f")))
  8738.      (clobber (match_scratch:HI 2 "=a"))]
  8739.     "TARGET_80387"
  8740. !   "* return (char *) output_float_compare (insn, operands);")
  8741.   
  8742.   (define_expand "cmpxf"
  8743.     [(set (cc0)
  8744. !       (compare (match_operand:XF 0 "register_operand" "")
  8745. !                (match_operand:XF 1 "nonimmediate_operand" "")))]
  8746.     "TARGET_80387"
  8747.     "
  8748.   {
  8749. ***************
  8750. *** 531,540 ****
  8751.     DONE;
  8752.   }")
  8753.   
  8754.   (define_expand "cmpdf"
  8755.     [(set (cc0)
  8756.       (compare (match_operand:DF 0 "register_operand" "")
  8757. !          (match_operand:DF 1 "nonimmediate_operand" "")))]
  8758.     "TARGET_80387"
  8759.     "
  8760.   {
  8761. --- 578,588 ----
  8762.     DONE;
  8763.   }")
  8764.   
  8765. + ;;intel1 operand 1 changed from nonimmediate_operand to general_operand
  8766.   (define_expand "cmpdf"
  8767.     [(set (cc0)
  8768.       (compare (match_operand:DF 0 "register_operand" "")
  8769. !          (match_operand:DF 1 "general_operand" "")))]
  8770.     "TARGET_80387"
  8771.     "
  8772.   {
  8773. ***************
  8774. *** 545,554 ****
  8775.     DONE;
  8776.   }")
  8777.   
  8778.   (define_expand "cmpsf"
  8779.     [(set (cc0)
  8780.       (compare (match_operand:SF 0 "register_operand" "")
  8781. !          (match_operand:SF 1 "nonimmediate_operand" "")))]
  8782.     "TARGET_80387"
  8783.     "
  8784.   {
  8785. --- 593,603 ----
  8786.     DONE;
  8787.   }")
  8788.   
  8789. + ;;intel1 operand 1 changed from nonimmediate_operand to general_operand
  8790.   (define_expand "cmpsf"
  8791.     [(set (cc0)
  8792.       (compare (match_operand:SF 0 "register_operand" "")
  8793. !          (match_operand:SF 1 "general_operand" "")))]
  8794.     "TARGET_80387"
  8795.     "
  8796.   {
  8797. ***************
  8798. *** 561,577 ****
  8799.   
  8800.   (define_expand "cmpxf_cc"
  8801.     [(parallel [(set (cc0)
  8802. !            (compare (match_operand:XF 0 "register_operand" "")
  8803. !                 (match_operand:XF 1 "register_operand" "")))
  8804. !           (clobber (match_scratch:HI 2 ""))])]
  8805.     "TARGET_80387"
  8806.     "")
  8807.   
  8808.   (define_expand "cmpxf_ccfpeq"
  8809.     [(parallel [(set (cc0)
  8810. !            (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
  8811. !                    (match_operand:XF 1 "register_operand" "")))
  8812. !           (clobber (match_scratch:HI 2 ""))])]
  8813.     "TARGET_80387"
  8814.     "
  8815.   {
  8816. --- 610,626 ----
  8817.   
  8818.   (define_expand "cmpxf_cc"
  8819.     [(parallel [(set (cc0)
  8820. !                  (compare (match_operand:XF 0 "register_operand" "")
  8821. !                           (match_operand:XF 1 "register_operand" "")))
  8822. !             (clobber (match_scratch:HI 2 ""))])]
  8823.     "TARGET_80387"
  8824.     "")
  8825.   
  8826.   (define_expand "cmpxf_ccfpeq"
  8827.     [(parallel [(set (cc0)
  8828. !                  (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
  8829. !                                  (match_operand:XF 1 "register_operand" "")))
  8830. !             (clobber (match_scratch:HI 2 ""))])]
  8831.     "TARGET_80387"
  8832.     "
  8833.   {
  8834. ***************
  8835. *** 742,748 ****
  8836.   (define_insn ""
  8837.     [(set (match_operand:SI 0 "push_operand" "=<")
  8838.       (match_operand:SI 1 "general_operand" "g"))]
  8839. !   "TARGET_386"
  8840.     "push%L0 %1")
  8841.   
  8842.   ;; On a 486, it is faster to move MEM to a REG and then push, rather than
  8843. --- 791,797 ----
  8844.   (define_insn ""
  8845.     [(set (match_operand:SI 0 "push_operand" "=<")
  8846.       (match_operand:SI 1 "general_operand" "g"))]
  8847. !   "! TARGET_486"
  8848.     "push%L0 %1")
  8849.   
  8850.   ;; On a 486, it is faster to move MEM to a REG and then push, rather than
  8851. ***************
  8852. *** 750,763 ****
  8853.   
  8854.   (define_insn ""
  8855.     [(set (match_operand:SI 0 "push_operand" "=<")
  8856. -     (match_operand:SI 1 "nonmemory_operand" "ri"))]
  8857. -   "!TARGET_386 && TARGET_MOVE"
  8858. -   "push%L0 %1")
  8859. - (define_insn ""
  8860. -   [(set (match_operand:SI 0 "push_operand" "=<")
  8861.       (match_operand:SI 1 "general_operand" "ri"))]
  8862. !   "!TARGET_386 && !TARGET_MOVE"
  8863.     "push%L0 %1")
  8864.   
  8865.   ;; General case of fullword move.
  8866. --- 799,806 ----
  8867.   
  8868.   (define_insn ""
  8869.     [(set (match_operand:SI 0 "push_operand" "=<")
  8870.       (match_operand:SI 1 "general_operand" "ri"))]
  8871. !   "TARGET_486"
  8872.     "push%L0 %1")
  8873.   
  8874.   ;; General case of fullword move.
  8875. ***************
  8876. *** 775,789 ****
  8877.   
  8878.     if (flag_pic && SYMBOLIC_CONST (operands[1]))
  8879.       emit_pic_move (operands, SImode);
  8880. -   /* Don't generate memory->memory moves, go through a register */
  8881. -   else if (TARGET_MOVE
  8882. -        && (reload_in_progress | reload_completed) == 0
  8883. -        && GET_CODE (operands[0]) == MEM
  8884. -        && GET_CODE (operands[1]) == MEM)
  8885. -     {
  8886. -       operands[1] = force_reg (SImode, operands[1]);
  8887. -     }
  8888.   }")
  8889.   
  8890.   ;; On i486, incl reg is faster than movl $1,reg.
  8891. --- 818,823 ----
  8892. ***************
  8893. *** 791,797 ****
  8894.   (define_insn ""
  8895.     [(set (match_operand:SI 0 "general_operand" "=g,r")
  8896.       (match_operand:SI 1 "general_operand" "ri,m"))]
  8897. !   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  8898.     "*
  8899.   {
  8900.     rtx link;
  8901. --- 825,831 ----
  8902.   (define_insn ""
  8903.     [(set (match_operand:SI 0 "general_operand" "=g,r")
  8904.       (match_operand:SI 1 "general_operand" "ri,m"))]
  8905. !   ""
  8906.     "*
  8907.   {
  8908.     rtx link;
  8909. ***************
  8910. *** 810,861 ****
  8911.       /* Fastest way to change a 0 to a 1.  */
  8912.       return AS1 (inc%L0,%0);
  8913.   
  8914. -   if (flag_pic && SYMBOLIC_CONST (operands[1]))
  8915. -     return AS2 (lea%L0,%a1,%0);
  8916.     return AS2 (mov%L0,%1,%0);
  8917.   }")
  8918.   
  8919.   (define_insn ""
  8920.     [(set (match_operand:HI 0 "push_operand" "=<")
  8921.       (match_operand:HI 1 "general_operand" "g"))]
  8922. !   "TARGET_386"
  8923. !   "push%W0 %1")
  8924. ! (define_insn ""
  8925. !   [(set (match_operand:HI 0 "push_operand" "=<")
  8926. !     (match_operand:HI 1 "nonmemory_operand" "ri"))]
  8927. !   "!TARGET_386 && TARGET_MOVE"
  8928. !   "push%W0 %1")
  8929. ! (define_insn ""
  8930. !   [(set (match_operand:HI 0 "push_operand" "=<")
  8931. !     (match_operand:HI 1 "general_operand" "ri"))]
  8932. !   "!TARGET_386 && !TARGET_MOVE"
  8933.     "push%W0 %1")
  8934.   
  8935.   ;; On i486, an incl and movl are both faster than incw and movw.
  8936.   
  8937. ! (define_expand "movhi"
  8938. !   [(set (match_operand:HI 0 "general_operand" "")
  8939. !     (match_operand:HI 1 "general_operand" ""))]
  8940. !   ""
  8941. !   "
  8942. ! {
  8943. !   /* Don't generate memory->memory moves, go through a register */
  8944. !   if (TARGET_MOVE
  8945. !       && (reload_in_progress | reload_completed) == 0
  8946. !       && GET_CODE (operands[0]) == MEM
  8947. !       && GET_CODE (operands[1]) == MEM)
  8948. !     {
  8949. !       operands[1] = force_reg (HImode, operands[1]);
  8950. !     }
  8951. ! }")
  8952. ! (define_insn ""
  8953.     [(set (match_operand:HI 0 "general_operand" "=g,r")
  8954.       (match_operand:HI 1 "general_operand" "ri,m"))]
  8955. !   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  8956.     "*
  8957.   {
  8958.     rtx link;
  8959. --- 844,864 ----
  8960.       /* Fastest way to change a 0 to a 1.  */
  8961.       return AS1 (inc%L0,%0);
  8962.   
  8963.     return AS2 (mov%L0,%1,%0);
  8964.   }")
  8965.   
  8966.   (define_insn ""
  8967.     [(set (match_operand:HI 0 "push_operand" "=<")
  8968.       (match_operand:HI 1 "general_operand" "g"))]
  8969. !   ""
  8970.     "push%W0 %1")
  8971.   
  8972.   ;; On i486, an incl and movl are both faster than incw and movw.
  8973.   
  8974. ! (define_insn "movhi"
  8975.     [(set (match_operand:HI 0 "general_operand" "=g,r")
  8976.       (match_operand:HI 1 "general_operand" "ri,m"))]
  8977. !   ""
  8978.     "*
  8979.   {
  8980.     rtx link;
  8981. ***************
  8982. *** 885,910 ****
  8983.     return AS2 (mov%W0,%1,%0);
  8984.   }")
  8985.   
  8986. ! (define_expand "movstricthi"
  8987. !   [(set (strict_low_part (match_operand:HI 0 "general_operand" ""))
  8988. !     (match_operand:HI 1 "general_operand" ""))]
  8989. !   ""
  8990. !   "
  8991. ! {
  8992. !   /* Don't generate memory->memory moves, go through a register */
  8993. !   if (TARGET_MOVE
  8994. !       && (reload_in_progress | reload_completed) == 0
  8995. !       && GET_CODE (operands[0]) == MEM
  8996. !       && GET_CODE (operands[1]) == MEM)
  8997. !     {
  8998. !       operands[1] = force_reg (HImode, operands[1]);
  8999. !     }
  9000. ! }")
  9001. ! (define_insn ""
  9002.     [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
  9003.       (match_operand:HI 1 "general_operand" "ri,m"))]
  9004. !   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  9005.     "*
  9006.   {
  9007.     rtx link;
  9008. --- 888,897 ----
  9009.     return AS2 (mov%W0,%1,%0);
  9010.   }")
  9011.   
  9012. ! (define_insn "movstricthi"
  9013.     [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
  9014.       (match_operand:HI 1 "general_operand" "ri,m"))]
  9015. !   ""
  9016.     "*
  9017.   {
  9018.     rtx link;
  9019. ***************
  9020. *** 932,955 ****
  9021.   ;; the amount pushed up to a halfword.
  9022.   (define_insn ""
  9023.     [(set (match_operand:QI 0 "push_operand" "=<")
  9024. !     (match_operand:QI 1 "immediate_operand" "n"))]
  9025.     ""
  9026. -   "* return AS1 (push%W0,%1);")
  9027. - (define_insn ""
  9028. -   [(set (match_operand:QI 0 "push_operand" "=<")
  9029. -     (match_operand:QI 1 "nonimmediate_operand" "q"))]
  9030. -   "!TARGET_MOVE"
  9031. -   "*
  9032. - {
  9033. -   operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
  9034. -   return AS1 (push%W0,%1);
  9035. - }")
  9036. - (define_insn ""
  9037. -   [(set (match_operand:QI 0 "push_operand" "=<")
  9038. -     (match_operand:QI 1 "register_operand" "q"))]
  9039. -   "TARGET_MOVE"
  9040.     "*
  9041.   {
  9042.     operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
  9043. --- 919,926 ----
  9044.   ;; the amount pushed up to a halfword.
  9045.   (define_insn ""
  9046.     [(set (match_operand:QI 0 "push_operand" "=<")
  9047. !     (match_operand:QI 1 "general_operand" "q"))]
  9048.     ""
  9049.     "*
  9050.   {
  9051.     operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
  9052. ***************
  9053. *** 961,986 ****
  9054.   ;; ??? Do a recognizer for zero_extract that looks just like this, but reads
  9055.   ;; or writes %ah, %bh, %ch, %dh.
  9056.   
  9057. ! (define_expand "movqi"
  9058. !   [(set (match_operand:QI 0 "general_operand" "")
  9059. !     (match_operand:QI 1 "general_operand" ""))]
  9060. !   ""
  9061. !   "
  9062. ! {
  9063. !   /* Don't generate memory->memory moves, go through a register */
  9064. !   if (TARGET_MOVE
  9065. !       && (reload_in_progress | reload_completed) == 0
  9066. !       && GET_CODE (operands[0]) == MEM
  9067. !       && GET_CODE (operands[1]) == MEM)
  9068. !     {
  9069. !       operands[1] = force_reg (QImode, operands[1]);
  9070. !     }
  9071. ! }")
  9072. ! (define_insn ""
  9073.     [(set (match_operand:QI 0 "general_operand" "=q,*r,qm")
  9074.       (match_operand:QI 1 "general_operand" "*g,q,qn"))]
  9075. !   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  9076.     "*
  9077.   {
  9078.     rtx link;
  9079. --- 932,941 ----
  9080.   ;; ??? Do a recognizer for zero_extract that looks just like this, but reads
  9081.   ;; or writes %ah, %bh, %ch, %dh.
  9082.   
  9083. ! (define_insn "movqi"
  9084.     [(set (match_operand:QI 0 "general_operand" "=q,*r,qm")
  9085.       (match_operand:QI 1 "general_operand" "*g,q,qn"))]
  9086. !   ""
  9087.     "*
  9088.   {
  9089.     rtx link;
  9090. ***************
  9091. *** 1015,1040 ****
  9092.   ;; If operands[1] is a constant, then an andl/orl sequence would be
  9093.   ;; faster.
  9094.   
  9095. ! (define_expand "movstrictqi"
  9096. !   [(set (strict_low_part (match_operand:QI 0 "general_operand" ""))
  9097. !     (match_operand:QI 1 "general_operand" ""))]
  9098. !   ""
  9099. !   "
  9100. ! {
  9101. !   /* Don't generate memory->memory moves, go through a register */
  9102. !   if (TARGET_MOVE
  9103. !       && (reload_in_progress | reload_completed) == 0
  9104. !       && GET_CODE (operands[0]) == MEM
  9105. !       && GET_CODE (operands[1]) == MEM)
  9106. !     {
  9107. !       operands[1] = force_reg (QImode, operands[1]);
  9108. !     }
  9109. ! }")
  9110. ! (define_insn ""
  9111.     [(set (strict_low_part (match_operand:QI 0 "general_operand" "+qm,q"))
  9112.       (match_operand:QI 1 "general_operand" "*qn,m"))]
  9113. !   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  9114.     "*
  9115.   {
  9116.     rtx link;
  9117. --- 970,979 ----
  9118.   ;; If operands[1] is a constant, then an andl/orl sequence would be
  9119.   ;; faster.
  9120.   
  9121. ! (define_insn "movstrictqi"
  9122.     [(set (strict_low_part (match_operand:QI 0 "general_operand" "+qm,q"))
  9123.       (match_operand:QI 1 "general_operand" "*qn,m"))]
  9124. !   ""
  9125.     "*
  9126.   {
  9127.     rtx link;
  9128. ***************
  9129. *** 1063,1105 ****
  9130.     return AS2 (mov%B0,%1,%0);
  9131.   }")
  9132.   
  9133. ! (define_expand "movsf"
  9134. !   [(set (match_operand:SF 0 "general_operand" "")
  9135. !     (match_operand:SF 1 "general_operand" ""))]
  9136. !   ""
  9137. !   "
  9138. ! {
  9139. !   /* Special case memory->memory moves and pushes */
  9140. !   if (TARGET_MOVE
  9141. !       && (reload_in_progress | reload_completed) == 0
  9142. !       && GET_CODE (operands[0]) == MEM
  9143. !       && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], SFmode)))
  9144. !     {
  9145. !       rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], SFmode))
  9146. !                         ? gen_movsf_push
  9147. !                         : gen_movsf_mem;
  9148. !       emit_insn ((*genfunc) (operands[0], operands[1]));
  9149. !       DONE;
  9150. !     }
  9151. !   /* If we are loading a floating point constant that isn't 0 or 1 into a register,
  9152. !      indicate we need the pic register loaded.  This could be optimized into stores
  9153. !      of constants if the target eventually moves to memory, but better safe than
  9154. !      sorry.  */
  9155. !   if (flag_pic
  9156. !       && GET_CODE (operands[0]) != MEM
  9157. !       && GET_CODE (operands[1]) == CONST_DOUBLE
  9158. !       && !standard_80387_constant_p (operands[1]))
  9159. !     {
  9160. !       current_function_uses_pic_offset_table = 1;
  9161. !     }
  9162. ! }")
  9163. ! (define_insn "movsf_push_nomove"
  9164.     [(set (match_operand:SF 0 "push_operand" "=<,<")
  9165.       (match_operand:SF 1 "general_operand" "gF,f"))]
  9166. !   "!TARGET_MOVE"
  9167.     "*
  9168.   {
  9169.     if (STACK_REG_P (operands[1]))
  9170. --- 1002,1011 ----
  9171.     return AS2 (mov%B0,%1,%0);
  9172.   }")
  9173.   
  9174. ! (define_insn ""
  9175.     [(set (match_operand:SF 0 "push_operand" "=<,<")
  9176.       (match_operand:SF 1 "general_operand" "gF,f"))]
  9177. !   ""
  9178.     "*
  9179.   {
  9180.     if (STACK_REG_P (operands[1]))
  9181. ***************
  9182. *** 1124,1184 ****
  9183.     return AS1 (push%L1,%1);
  9184.   }")
  9185.   
  9186. ! (define_insn "movsf_push"
  9187. !   [(set (match_operand:SF 0 "push_operand" "=<,<,<,<")
  9188. !     (match_operand:SF 1 "general_operand" "rF,f,m,m"))
  9189. !    (clobber (match_scratch:SI 2 "=X,X,r,X"))]
  9190. !   ""
  9191. !   "*
  9192. ! {
  9193. !   if (STACK_REG_P (operands[1]))
  9194. !     {
  9195. !       rtx xops[3];
  9196. !       if (! STACK_TOP_P (operands[1]))
  9197. !         abort ();
  9198. !       xops[0] = AT_SP (SFmode);
  9199. !       xops[1] = GEN_INT (4);
  9200. !       xops[2] = stack_pointer_rtx;
  9201. !       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  9202. !       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  9203. !         output_asm_insn (AS1 (fstp%S0,%0), xops);
  9204. !       else
  9205. !         output_asm_insn (AS1 (fst%S0,%0), xops);
  9206. !       RET;
  9207. !     }
  9208. !   else if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != REG)
  9209. !     return AS1 (push%L1,%1);
  9210. !   else
  9211. !     {
  9212. !       output_asm_insn (AS2 (mov%L2,%1,%2), operands);
  9213. !       return AS1 (push%L2,%2);
  9214. !     }
  9215. ! }")
  9216.   
  9217. ! ;; Special memory<->memory pattern that combine will recreate from the
  9218. ! ;; moves to pseudos.
  9219. ! (define_insn "movsf_mem"
  9220. !   [(set (match_operand:SF 0 "memory_operand" "=m")
  9221. !     (match_operand:SF 1 "memory_operand" "m"))
  9222. !    (clobber (match_scratch:SI 2 "=&r"))]
  9223.     ""
  9224.     "*
  9225.   {
  9226. !   output_asm_insn (AS2 (mov%L2,%1,%2), operands);
  9227. !   return AS2 (mov%L0,%2,%0);
  9228.   }")
  9229.   
  9230. ! ;; For the purposes of regclass, prefer FLOAT_REGS.
  9231. ! (define_insn "movsf_normal"
  9232.     [(set (match_operand:SF 0 "general_operand" "=*rfm,*rf,f,!*rm")
  9233.       (match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))]
  9234. !   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  9235.     "*
  9236.   {
  9237.     int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  9238. --- 1030,1053 ----
  9239.     return AS1 (push%L1,%1);
  9240.   }")
  9241.   
  9242. ! ;; Allow MEM-MEM moves before reload.  The reload class for such a
  9243. ! ;; move will be ALL_REGS.  PREFERRED_RELOAD_CLASS will narrow this to
  9244. ! ;; GENERAL_REGS.  For the purposes of regclass, prefer FLOAT_REGS.
  9245.   
  9246. ! ;;intel1
  9247. ! (define_insn "memmovsf"
  9248. !   [(set (match_operand:SF 0 "memory_operand" "=r,m")
  9249. !     (match_operand:SF 1 "memory_operand" "m,r"))]
  9250.     ""
  9251.     "*
  9252.   {
  9253. !   return (char *) singlemove_string (operands);
  9254.   }")
  9255.   
  9256. ! (define_insn "movsf"
  9257.     [(set (match_operand:SF 0 "general_operand" "=*rfm,*rf,f,!*rm")
  9258.       (match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))]
  9259. !   ""
  9260.     "*
  9261.   {
  9262.     int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  9263. ***************
  9264. *** 1220,1286 ****
  9265.     /* Handle other kinds of reads to the 387 */
  9266.   
  9267.     if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  9268. !     return output_move_const_single (operands);
  9269.   
  9270.     if (STACK_TOP_P (operands[0]))
  9271.       return AS1 (fld%z1,%y1);
  9272.   
  9273.     /* Handle all SFmode moves not involving the 387 */
  9274.   
  9275. !   return singlemove_string (operands);
  9276. ! }")
  9277. ! (define_insn "swapsf"
  9278. !   [(set (match_operand:SF 0 "register_operand" "f")
  9279. !     (match_operand:SF 1 "register_operand" "f"))
  9280. !    (set (match_dup 1)
  9281. !     (match_dup 0))]
  9282. !   ""
  9283. !   "*
  9284. ! {
  9285. !   if (STACK_TOP_P (operands[0]))
  9286. !     return AS1 (fxch,%1);
  9287. !   else
  9288. !     return AS1 (fxch,%0);
  9289. ! }")
  9290. ! (define_expand "movdf"
  9291. !   [(set (match_operand:DF 0 "general_operand" "")
  9292. !     (match_operand:DF 1 "general_operand" ""))]
  9293. !   ""
  9294. !   "
  9295. ! {
  9296. !   /* Special case memory->memory moves and pushes */
  9297. !   if (TARGET_MOVE
  9298. !       && (reload_in_progress | reload_completed) == 0
  9299. !       && GET_CODE (operands[0]) == MEM
  9300. !       && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], DFmode)))
  9301. !     {
  9302. !       rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], DFmode))
  9303. !                         ? gen_movdf_push
  9304. !                         : gen_movdf_mem;
  9305. !       emit_insn ((*genfunc) (operands[0], operands[1]));
  9306. !       DONE;
  9307. !     }
  9308. !   /* If we are loading a floating point constant that isn't 0 or 1 into a register,
  9309. !      indicate we need the pic register loaded.  This could be optimized into stores
  9310. !      of constants if the target eventually moves to memory, but better safe than
  9311. !      sorry.  */
  9312. !   if (flag_pic
  9313. !       && GET_CODE (operands[0]) != MEM
  9314. !       && GET_CODE (operands[1]) == CONST_DOUBLE
  9315. !       && !standard_80387_constant_p (operands[1]))
  9316. !     {
  9317. !       current_function_uses_pic_offset_table = 1;
  9318. !     }
  9319. ! }")
  9320.   
  9321. ! (define_insn "movdf_push_nomove"
  9322.     [(set (match_operand:DF 0 "push_operand" "=<,<")
  9323.       (match_operand:DF 1 "general_operand" "gF,f"))]
  9324. !   "!TARGET_MOVE"
  9325.     "*
  9326.   {
  9327.     if (STACK_REG_P (operands[1]))
  9328. --- 1089,1109 ----
  9329.     /* Handle other kinds of reads to the 387 */
  9330.   
  9331.     if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  9332. !     return (char *) output_move_const_single (operands);
  9333.   
  9334.     if (STACK_TOP_P (operands[0]))
  9335.       return AS1 (fld%z1,%y1);
  9336.   
  9337.     /* Handle all SFmode moves not involving the 387 */
  9338.   
  9339. !   return (char *) singlemove_string (operands);
  9340. ! }"[(set_attr "type" "fld")])
  9341.   
  9342. ! ;;should change to handle the memory operands[1] without doing df push..
  9343. ! (define_insn ""
  9344.     [(set (match_operand:DF 0 "push_operand" "=<,<")
  9345.       (match_operand:DF 1 "general_operand" "gF,f"))]
  9346. !   ""
  9347.     "*
  9348.   {
  9349.     if (STACK_REG_P (operands[1]))
  9350. ***************
  9351. *** 1301,1355 ****
  9352.         RET;
  9353.       }
  9354.     else
  9355. !     return output_move_double (operands);
  9356.   }")
  9357.   
  9358. ! (define_insn "movdf_push"
  9359. !   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<")
  9360. !     (match_operand:DF 1 "general_operand" "rF,f,o,o,o"))
  9361. !    (clobber (match_scratch:SI 2 "=X,X,&r,&r,X"))
  9362. !    (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))]
  9363.     ""
  9364.     "*
  9365.   {
  9366. !   if (STACK_REG_P (operands[1]))
  9367. !     {
  9368. !       rtx xops[3];
  9369. !       xops[0] = AT_SP (SFmode);
  9370. !       xops[1] = GEN_INT (8);
  9371. !       xops[2] = stack_pointer_rtx;
  9372. !       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  9373. !       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  9374. !         output_asm_insn (AS1 (fstp%Q0,%0), xops);
  9375. !       else
  9376. !         output_asm_insn (AS1 (fst%Q0,%0), xops);
  9377. !       RET;
  9378. !     }
  9379. !   else if (GET_CODE (operands[1]) != MEM)
  9380. !     return output_move_double (operands);
  9381.     else
  9382. !     return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);
  9383.   }")
  9384.   
  9385. ! (define_insn "movdf_mem"
  9386. !   [(set (match_operand:DF 0 "memory_operand" "=o,o")
  9387. !     (match_operand:DF 1 "memory_operand" "o,o"))
  9388. !    (clobber (match_scratch:SI 2 "=&r,&r"))
  9389. !    (clobber (match_scratch:SI 3 "=&r,X"))]
  9390.     ""
  9391. !   "* return output_move_memory (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);")
  9392.   
  9393. ! ;; For the purposes of regclass, prefer FLOAT_REGS.
  9394. ! (define_insn "movdf_normal"
  9395. !   [(set (match_operand:DF 0 "general_operand" "=f,fm,!*rf,!*rm")
  9396. !     (match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
  9397. !   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  9398.     "*
  9399.   {
  9400.     int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  9401. --- 1124,1164 ----
  9402.         RET;
  9403.       }
  9404.     else
  9405. !     return (char *) output_move_double (operands);
  9406.   }")
  9407.   
  9408. ! (define_insn "swapdf"
  9409. !   [(set (match_operand:DF 0 "register_operand" "f")
  9410. !     (match_operand:DF 1 "register_operand" "f"))
  9411. !    (set (match_dup 1)
  9412. !     (match_dup 0))]
  9413.     ""
  9414.     "*
  9415.   {
  9416. !   if (STACK_TOP_P (operands[0]))
  9417. !     return AS1 (fxch,%1);
  9418.     else
  9419. !     return AS1 (fxch,%0);
  9420.   }")
  9421.   
  9422. ! ;; Allow MEM-MEM moves before reload.  The reload class for such a
  9423. ! ;; move will be ALL_REGS.  PREFERRED_RELOAD_CLASS will narrow this to
  9424. ! ;; GENERAL_REGS.  For the purposes of regclass, prefer FLOAT_REGS.
  9425. ! ;;intel1
  9426. ! (define_insn "memmovdf"
  9427. !   [(set (match_operand:DF 0 "memory_operand" "=r,m")
  9428. !     (match_operand:DF 1 "memory_operand" "m,r"))]
  9429.     ""
  9430. !   "*
  9431. ! {
  9432. !   return (char *) output_move_double (operands);
  9433. ! }")
  9434.   
  9435. ! (define_insn "movdf"
  9436. !   [(set (match_operand:DF 0 "general_operand" "=*rfm,*rf,f,!*rm")
  9437. !     (match_operand:DF 1 "general_operand" "*rf,*rfm,fG,fF"))]
  9438. !   ""
  9439.     "*
  9440.   {
  9441.     int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  9442. ***************
  9443. *** 1391,1458 ****
  9444.     /* Handle other kinds of reads to the 387 */
  9445.   
  9446.     if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  9447. !     return output_move_const_single (operands);
  9448.   
  9449.     if (STACK_TOP_P (operands[0]))
  9450.       return AS1 (fld%z1,%y1);
  9451.   
  9452.     /* Handle all DFmode moves not involving the 387 */
  9453.   
  9454. !   return output_move_double (operands);
  9455. ! }")
  9456.   
  9457. ! (define_insn "swapdf"
  9458. !   [(set (match_operand:DF 0 "register_operand" "f")
  9459. !     (match_operand:DF 1 "register_operand" "f"))
  9460. !    (set (match_dup 1)
  9461. !     (match_dup 0))]
  9462. !   ""
  9463. !   "*
  9464. ! {
  9465. !   if (STACK_TOP_P (operands[0]))
  9466. !     return AS1 (fxch,%1);
  9467. !   else
  9468. !     return AS1 (fxch,%0);
  9469. ! }")
  9470. ! (define_expand "movxf"
  9471. !   [(set (match_operand:XF 0 "general_operand" "")
  9472. !     (match_operand:XF 1 "general_operand" ""))]
  9473. !   ""
  9474. !   "
  9475. ! {
  9476. !   /* Special case memory->memory moves and pushes */
  9477. !   if (TARGET_MOVE
  9478. !       && (reload_in_progress | reload_completed) == 0
  9479. !       && GET_CODE (operands[0]) == MEM
  9480. !       && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], XFmode)))
  9481. !     {
  9482. !       rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], XFmode))
  9483. !                         ? gen_movxf_push
  9484. !                         : gen_movxf_mem;
  9485. !       emit_insn ((*genfunc) (operands[0], operands[1]));
  9486. !       DONE;
  9487. !     }
  9488. !   /* If we are loading a floating point constant that isn't 0 or 1 into a register,
  9489. !      indicate we need the pic register loaded.  This could be optimized into stores
  9490. !      of constants if the target eventually moves to memory, but better safe than
  9491. !      sorry.  */
  9492. !   if (flag_pic
  9493. !       && GET_CODE (operands[0]) != MEM
  9494. !       && GET_CODE (operands[1]) == CONST_DOUBLE
  9495. !       && !standard_80387_constant_p (operands[1]))
  9496. !     {
  9497. !       current_function_uses_pic_offset_table = 1;
  9498. !     }
  9499. ! }")
  9500. ! (define_insn "movxf_push_nomove"
  9501.     [(set (match_operand:XF 0 "push_operand" "=<,<")
  9502.        (match_operand:XF 1 "general_operand" "gF,f"))]
  9503. !   "!TARGET_MOVE"
  9504.     "*
  9505.   {
  9506.     if (STACK_REG_P (operands[1]))
  9507. --- 1200,1219 ----
  9508.     /* Handle other kinds of reads to the 387 */
  9509.   
  9510.     if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  9511. !     return (char *) output_move_const_single (operands);
  9512.   
  9513.     if (STACK_TOP_P (operands[0]))
  9514.       return AS1 (fld%z1,%y1);
  9515.   
  9516.     /* Handle all DFmode moves not involving the 387 */
  9517.   
  9518. !   return (char *) output_move_double (operands);
  9519. ! }"[(set_attr "type" "fld")])
  9520.   
  9521. ! (define_insn ""
  9522.     [(set (match_operand:XF 0 "push_operand" "=<,<")
  9523.        (match_operand:XF 1 "general_operand" "gF,f"))]
  9524. !   ""
  9525.     "*
  9526.   {
  9527.     if (STACK_REG_P (operands[1]))
  9528. ***************
  9529. *** 1471,1523 ****
  9530.         RET;
  9531.       }
  9532.     else
  9533. !     return output_move_double (operands);
  9534.    }")
  9535.   
  9536. ! (define_insn "movxf_push"
  9537. !   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
  9538. !      (match_operand:XF 1 "general_operand" "rF,f,o,o,o"))
  9539. !    (clobber (match_scratch:SI 2 "=X,X,&r,&r,X"))
  9540. !    (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))]
  9541.     ""
  9542.     "*
  9543.   {
  9544. !   if (STACK_REG_P (operands[1]))
  9545. !     {
  9546. !       rtx xops[3];
  9547. !       xops[0] = AT_SP (SFmode);
  9548. !       xops[1] = GEN_INT (12);
  9549. !       xops[2] = stack_pointer_rtx;
  9550. !       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  9551. !       output_asm_insn (AS1 (fstp%T0,%0), xops);
  9552. !       if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  9553. !     output_asm_insn (AS1 (fld%T0,%0), xops);
  9554. !       RET;
  9555. !     }
  9556. !   else if (GET_CODE (operands[1]) != MEM
  9557. !        || GET_CODE (operands[2]) != REG)
  9558. !     return output_move_double (operands);
  9559.     else
  9560. !     return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);
  9561.   }")
  9562.   
  9563. ! (define_insn "movxf_mem"
  9564. !   [(set (match_operand:XF 0 "memory_operand" "=o,o")
  9565. !     (match_operand:XF 1 "memory_operand" "o,o"))
  9566. !    (clobber (match_scratch:SI 2 "=&r,&r"))
  9567. !    (clobber (match_scratch:SI 3 "=&r,X"))]
  9568. !   ""
  9569. !   "* return output_move_memory (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);")
  9570. ! (define_insn "movxf_normal"
  9571.     [(set (match_operand:XF 0 "general_operand" "=f,fm,!*rf,!*rm")
  9572.       (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
  9573. !   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  9574.     "*
  9575.   {
  9576.     int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  9577. --- 1232,1260 ----
  9578.         RET;
  9579.       }
  9580.     else
  9581. !     return (char *) output_move_double (operands);
  9582.    }")
  9583.   
  9584. ! (define_insn "swapxf"
  9585. !   [(set (match_operand:XF 0 "register_operand" "f")
  9586. !     (match_operand:XF 1 "register_operand" "f"))
  9587. !    (set (match_dup 1)
  9588. !     (match_dup 0))]
  9589.     ""
  9590.     "*
  9591.   {
  9592. !   if (STACK_TOP_P (operands[0]))
  9593. !     return AS1 (fxch,%1);
  9594.     else
  9595. !     return AS1 (fxch,%0);
  9596.   }")
  9597.   
  9598. ! (define_insn "movxf"
  9599.     [(set (match_operand:XF 0 "general_operand" "=f,fm,!*rf,!*rm")
  9600.       (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
  9601. ! ;;  [(set (match_operand:XF 0 "general_operand" "=*rf,*rfm,f,!*rm")
  9602. ! ;;    (match_operand:XF 1 "general_operand" "*rfm,*rf,fG,fF"))]
  9603. !   ""
  9604.     "*
  9605.   {
  9606.     int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  9607. ***************
  9608. *** 1560,1620 ****
  9609.     /* Handle other kinds of reads to the 387 */
  9610.   
  9611.     if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  9612. !     return output_move_const_single (operands);
  9613.   
  9614.     if (STACK_TOP_P (operands[0]))
  9615.          return AS1 (fld%z1,%y1);
  9616.   
  9617.     /* Handle all XFmode moves not involving the 387 */
  9618.   
  9619. !   return output_move_double (operands);
  9620. ! }")
  9621. ! (define_insn "swapxf"
  9622. !   [(set (match_operand:XF 0 "register_operand" "f")
  9623. !     (match_operand:XF 1 "register_operand" "f"))
  9624. !    (set (match_dup 1)
  9625. !     (match_dup 0))]
  9626. !   ""
  9627. !   "*
  9628. ! {
  9629. !   if (STACK_TOP_P (operands[0]))
  9630. !     return AS1 (fxch,%1);
  9631. !   else
  9632. !     return AS1 (fxch,%0);
  9633.   }")
  9634.   
  9635.   (define_insn ""
  9636. !   [(set (match_operand:DI 0 "push_operand" "=<,<,<,<")
  9637. !     (match_operand:DI 1 "general_operand" "riF,o,o,o"))
  9638. !    (clobber (match_scratch:SI 2 "=X,&r,&r,X"))
  9639. !    (clobber (match_scratch:SI 3 "=X,&r,X,X"))]
  9640.     ""
  9641.     "*
  9642.   {
  9643. !   if (GET_CODE (operands[1]) != MEM)
  9644. !     return output_move_double (operands);
  9645. !   else
  9646. !     return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode), 2, 4);
  9647.   }")
  9648.   
  9649.   (define_insn "movdi"
  9650. !   [(set (match_operand:DI 0 "general_operand" "=o,o,r,rm")
  9651. !     (match_operand:DI 1 "general_operand" "o,o,m,riF"))
  9652. !    (clobber (match_scratch:SI 2 "=&r,&r,X,X"))
  9653. !    (clobber (match_scratch:SI 3 "=&r,X,X,X"))]
  9654.     ""
  9655.     "*
  9656.   {
  9657. !   rtx low[2], high[2], xop[6];
  9658. !   if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
  9659. !     return output_move_double (operands);
  9660. !   else
  9661. !     return output_move_memory (operands, insn, GET_MODE_SIZE (DImode), 2, 4);
  9662.   }")
  9663.   
  9664.   ;;- conversion instructions
  9665.   ;;- NONE
  9666. --- 1297,1329 ----
  9667.     /* Handle other kinds of reads to the 387 */
  9668.   
  9669.     if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  9670. !     return (char *) output_move_const_single (operands);
  9671.   
  9672.     if (STACK_TOP_P (operands[0]))
  9673.          return AS1 (fld%z1,%y1);
  9674.   
  9675.     /* Handle all XFmode moves not involving the 387 */
  9676.   
  9677. !   return (char *) output_move_double (operands);
  9678.   }")
  9679.   
  9680.   (define_insn ""
  9681. !   [(set (match_operand:DI 0 "push_operand" "=<")
  9682. !     (match_operand:DI 1 "general_operand" "roiF"))]
  9683.     ""
  9684.     "*
  9685.   {
  9686. !   return (char *) output_move_double (operands);
  9687.   }")
  9688.   
  9689.   (define_insn "movdi"
  9690. !   [(set (match_operand:DI 0 "general_operand" "=r,rm")
  9691. !     (match_operand:DI 1 "general_operand" "m,riF"))]
  9692.     ""
  9693.     "*
  9694.   {
  9695. !   return (char *) output_move_double (operands);
  9696.   }")
  9697.   
  9698.   ;;- conversion instructions
  9699.   ;;- NONE
  9700. ***************
  9701. *** 1629,1635 ****
  9702.     ""
  9703.     "*
  9704.   {
  9705. !   if ((!TARGET_386 || REGNO (operands[0]) == 0)
  9706.         && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  9707.       {
  9708.         rtx xops[2];
  9709. --- 1338,1344 ----
  9710.     ""
  9711.     "*
  9712.   {
  9713. !   if (((TARGET_486 || TARGET_PENTIUM) || REGNO (operands[0]) == 0)
  9714.         && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  9715.       {
  9716.         rtx xops[2];
  9717. ***************
  9718. *** 1639,1644 ****
  9719. --- 1348,1372 ----
  9720.         RET;
  9721.       }
  9722.   
  9723. +   if ((((TARGET_486 || TARGET_PENTIUM))) 
  9724. +        && !reg_overlap_mentioned_p(operands[0],operands[1]))
  9725. +   {
  9726. +     rtx xops[2];
  9727. +       output_asm_insn (AS2 (xor%L0,%0,%0),operands);
  9728. +       output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
  9729. +     RET;
  9730. +   }
  9731. +   if ((TARGET_486 || TARGET_PENTIUM))
  9732. +   {
  9733. +     rtx xops[2];
  9734. +       xops[0] = operands[0];
  9735. +       xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xffff);
  9736. +       output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
  9737. +       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
  9738. +     RET;
  9739. +   }
  9740.   #ifdef INTEL_SYNTAX
  9741.     return AS2 (movzx,%1,%0);
  9742.   #else
  9743. ***************
  9744. *** 1653,1659 ****
  9745.     ""
  9746.     "*
  9747.   {
  9748. !   if ((!TARGET_386 || REGNO (operands[0]) == 0)
  9749.         && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  9750.       {
  9751.         rtx xops[2];
  9752. --- 1381,1387 ----
  9753.     ""
  9754.     "*
  9755.   {
  9756. !   if (((TARGET_486 || TARGET_PENTIUM) || REGNO (operands[0]) == 0)
  9757.         && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  9758.       {
  9759.         rtx xops[2];
  9760. ***************
  9761. *** 1663,1668 ****
  9762. --- 1391,1416 ----
  9763.         RET;
  9764.       }
  9765.   
  9766. +     /* intel1 */
  9767. +   if ((((TARGET_486 || TARGET_PENTIUM))) &&
  9768. +        reg_fits_class_p (operands[0], Q_REGS, 0, SImode))
  9769. +   {
  9770. +     rtx xops[2];
  9771. +     if(!reg_overlap_mentioned_p(operands[0],operands[1]))
  9772. +     {
  9773. +       output_asm_insn (AS2 (xor%L0,%k0,%k0),operands);
  9774. +       output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
  9775. +     }
  9776. +     else
  9777. +     {
  9778. +       xops[0] = operands[0];
  9779. +       xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff);
  9780. +       output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
  9781. +       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
  9782. +     }
  9783. +     RET;
  9784. +   }
  9785.   #ifdef INTEL_SYNTAX
  9786.     return AS2 (movzx,%1,%0);
  9787.   #else
  9788. ***************
  9789. *** 1677,1683 ****
  9790.     ""
  9791.     "*
  9792.   {
  9793. !   if ((!TARGET_386 || REGNO (operands[0]) == 0)
  9794.         && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  9795.       {
  9796.         rtx xops[2];
  9797. --- 1425,1431 ----
  9798.     ""
  9799.     "*
  9800.   {
  9801. !   if (((TARGET_486 || TARGET_PENTIUM) || REGNO (operands[0]) == 0)
  9802.         && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  9803.       {
  9804.         rtx xops[2];
  9805. ***************
  9806. *** 1687,1692 ****
  9807. --- 1435,1471 ----
  9808.         RET;
  9809.       }
  9810.   
  9811. +     /* intel1 */
  9812. +   if ((((TARGET_486 || TARGET_PENTIUM))) &&
  9813. +        reg_fits_class_p (operands[0], Q_REGS, 0, SImode))
  9814. +   {
  9815. +     rtx xops[2];
  9816. +     if(!reg_overlap_mentioned_p(operands[0],operands[1]))
  9817. +     {
  9818. +       output_asm_insn (AS2 (xor%L0,%0,%0),operands);
  9819. +       output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
  9820. +     }
  9821. +     else
  9822. +     {
  9823. +       xops[0] = operands[0];
  9824. +       xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff);
  9825. +       output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
  9826. +       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
  9827. +     }
  9828. +     RET;
  9829. +   }
  9830. +   if ((TARGET_486 || TARGET_PENTIUM) && GET_CODE (operands[1]) == REG)
  9831. +   {
  9832. +     rtx xops[2];
  9833. +       xops[0] = operands[0];
  9834. +       operands[1] = gen_rtx (REG, SImode, REGNO (operands[1]));
  9835. +       xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff);
  9836. +       output_asm_insn (AS2 (mov%L0,%1,%0),operands);
  9837. +       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
  9838. +     RET;
  9839. +   }
  9840.   #ifdef INTEL_SYNTAX
  9841.     return AS2 (movzx,%1,%0);
  9842.   #else
  9843. ***************
  9844. *** 2013,2027 ****
  9845.   
  9846.   (define_expand "fixuns_truncxfsi2"
  9847.     [(set (match_dup 4)
  9848. !     (match_operand:XF 1 "register_operand" ""))
  9849.      (parallel [(set (match_dup 2)
  9850. !            (fix:DI (fix:XF (match_dup 4))))
  9851. !           (clobber (match_dup 4))
  9852. !           (clobber (match_dup 5))
  9853. !           (clobber (match_dup 6))
  9854. !           (clobber (match_scratch:SI 7 ""))])
  9855.      (set (match_operand:SI 0 "general_operand" "")
  9856. !     (match_dup 3))]
  9857.     "TARGET_80387"
  9858.     "
  9859.   {
  9860. --- 1792,1806 ----
  9861.   
  9862.   (define_expand "fixuns_truncxfsi2"
  9863.     [(set (match_dup 4)
  9864. !       (match_operand:XF 1 "register_operand" ""))
  9865.      (parallel [(set (match_dup 2)
  9866. !                  (fix:DI (fix:XF (match_dup 4))))
  9867. !             (clobber (match_dup 4))
  9868. !             (clobber (match_dup 5))
  9869. !             (clobber (match_dup 6))
  9870. !             (clobber (match_scratch:SI 7 ""))])
  9871.      (set (match_operand:SI 0 "general_operand" "")
  9872. !       (match_dup 3))]
  9873.     "TARGET_80387"
  9874.     "
  9875.   {
  9876. ***************
  9877. *** 2078,2090 ****
  9878.   
  9879.   (define_expand "fix_truncxfdi2"
  9880.     [(set (match_dup 2)
  9881. !     (match_operand:XF 1 "register_operand" ""))
  9882.      (parallel [(set (match_operand:DI 0 "general_operand" "")
  9883. !            (fix:DI (fix:XF (match_dup 2))))
  9884. !           (clobber (match_dup 2))
  9885. !           (clobber (match_dup 3))
  9886. !           (clobber (match_dup 4))
  9887. !           (clobber (match_scratch:SI 5 ""))])]
  9888.     "TARGET_80387"
  9889.     "
  9890.   {
  9891. --- 1857,1869 ----
  9892.   
  9893.   (define_expand "fix_truncxfdi2"
  9894.     [(set (match_dup 2)
  9895. !       (match_operand:XF 1 "register_operand" ""))
  9896.      (parallel [(set (match_operand:DI 0 "general_operand" "")
  9897. !                  (fix:DI (fix:XF (match_dup 2))))
  9898. !             (clobber (match_dup 2))
  9899. !             (clobber (match_dup 3))
  9900. !             (clobber (match_dup 4))
  9901. !             (clobber (match_scratch:SI 5 ""))])]
  9902.     "TARGET_80387"
  9903.     "
  9904.   {
  9905. ***************
  9906. *** 2134,2156 ****
  9907.   
  9908.   (define_insn ""
  9909.     [(set (match_operand:DI 0 "general_operand" "=rm")
  9910. !     (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
  9911.      (clobber (match_dup 1))
  9912.      (clobber (match_operand:SI 2 "memory_operand" "m"))
  9913.      (clobber (match_operand:SI 3 "memory_operand" "m"))
  9914.      (clobber (match_scratch:SI 4 "=&q"))]
  9915.     "TARGET_80387"
  9916. !   "* return output_fix_trunc (insn, operands);")
  9917.   
  9918.   (define_insn ""
  9919. !   [(set (match_operand:DI 0 "general_operand" "=rm")
  9920. !     (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
  9921.      (clobber (match_dup 1))
  9922.      (clobber (match_operand:SI 2 "memory_operand" "m"))
  9923.      (clobber (match_operand:SI 3 "memory_operand" "m"))
  9924.      (clobber (match_scratch:SI 4 "=&q"))]
  9925.     "TARGET_80387"
  9926. !   "* return output_fix_trunc (insn, operands);")
  9927.   
  9928.   (define_insn ""
  9929.     [(set (match_operand:DI 0 "general_operand" "=rm")
  9930. --- 1913,1935 ----
  9931.   
  9932.   (define_insn ""
  9933.     [(set (match_operand:DI 0 "general_operand" "=rm")
  9934. !       (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
  9935.      (clobber (match_dup 1))
  9936.      (clobber (match_operand:SI 2 "memory_operand" "m"))
  9937.      (clobber (match_operand:SI 3 "memory_operand" "m"))
  9938.      (clobber (match_scratch:SI 4 "=&q"))]
  9939.     "TARGET_80387"
  9940. !   "* return (char *) output_fix_trunc (insn, operands);")
  9941.   
  9942.   (define_insn ""
  9943. !    [(set (match_operand:DI 0 "general_operand" "=rm")
  9944. !        (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
  9945.      (clobber (match_dup 1))
  9946.      (clobber (match_operand:SI 2 "memory_operand" "m"))
  9947.      (clobber (match_operand:SI 3 "memory_operand" "m"))
  9948.      (clobber (match_scratch:SI 4 "=&q"))]
  9949.     "TARGET_80387"
  9950. !   "* return (char *) output_fix_trunc (insn, operands);")
  9951.   
  9952.   (define_insn ""
  9953.     [(set (match_operand:DI 0 "general_operand" "=rm")
  9954. ***************
  9955. *** 2160,2176 ****
  9956.      (clobber (match_operand:SI 3 "memory_operand" "m"))
  9957.      (clobber (match_scratch:SI 4 "=&q"))]
  9958.     "TARGET_80387"
  9959. !   "* return output_fix_trunc (insn, operands);")
  9960.   
  9961.   ;; Signed MODE_FLOAT conversion to SImode.
  9962.   
  9963.   (define_expand "fix_truncxfsi2"
  9964.     [(parallel [(set (match_operand:SI 0 "general_operand" "")
  9965. !            (fix:SI
  9966. !             (fix:XF (match_operand:XF 1 "register_operand" ""))))
  9967. !           (clobber (match_dup 2))
  9968. !           (clobber (match_dup 3))
  9969. !           (clobber (match_scratch:SI 4 ""))])]
  9970.     "TARGET_80387"
  9971.     "
  9972.   {
  9973. --- 1939,1955 ----
  9974.      (clobber (match_operand:SI 3 "memory_operand" "m"))
  9975.      (clobber (match_scratch:SI 4 "=&q"))]
  9976.     "TARGET_80387"
  9977. !   "* return (char *) output_fix_trunc (insn, operands);")
  9978.   
  9979.   ;; Signed MODE_FLOAT conversion to SImode.
  9980.   
  9981.   (define_expand "fix_truncxfsi2"
  9982.     [(parallel [(set (match_operand:SI 0 "general_operand" "")
  9983. !                  (fix:SI
  9984. !                   (fix:XF (match_operand:XF 1 "register_operand" ""))))
  9985. !             (clobber (match_dup 2))
  9986. !             (clobber (match_dup 3))
  9987. !             (clobber (match_scratch:SI 4 ""))])]
  9988.     "TARGET_80387"
  9989.     "
  9990.   {
  9991. ***************
  9992. *** 2208,2228 ****
  9993.   
  9994.   (define_insn ""
  9995.     [(set (match_operand:SI 0 "general_operand" "=rm")
  9996. !     (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
  9997.      (clobber (match_operand:SI 2 "memory_operand" "m"))
  9998.      (clobber (match_operand:SI 3 "memory_operand" "m"))
  9999.      (clobber (match_scratch:SI 4 "=&q"))]
  10000.     "TARGET_80387"
  10001. !   "* return output_fix_trunc (insn, operands);")
  10002.   
  10003.   (define_insn ""
  10004.     [(set (match_operand:SI 0 "general_operand" "=rm")
  10005. !     (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
  10006.      (clobber (match_operand:SI 2 "memory_operand" "m"))
  10007.      (clobber (match_operand:SI 3 "memory_operand" "m"))
  10008.      (clobber (match_scratch:SI 4 "=&q"))]
  10009.     "TARGET_80387"
  10010. !   "* return output_fix_trunc (insn, operands);")
  10011.   
  10012.   (define_insn ""
  10013.     [(set (match_operand:SI 0 "general_operand" "=rm")
  10014. --- 1987,2007 ----
  10015.   
  10016.   (define_insn ""
  10017.     [(set (match_operand:SI 0 "general_operand" "=rm")
  10018. !       (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
  10019.      (clobber (match_operand:SI 2 "memory_operand" "m"))
  10020.      (clobber (match_operand:SI 3 "memory_operand" "m"))
  10021.      (clobber (match_scratch:SI 4 "=&q"))]
  10022.     "TARGET_80387"
  10023. !   "* return (char *) output_fix_trunc (insn, operands);")
  10024.   
  10025.   (define_insn ""
  10026.     [(set (match_operand:SI 0 "general_operand" "=rm")
  10027. !       (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
  10028.      (clobber (match_operand:SI 2 "memory_operand" "m"))
  10029.      (clobber (match_operand:SI 3 "memory_operand" "m"))
  10030.      (clobber (match_scratch:SI 4 "=&q"))]
  10031.     "TARGET_80387"
  10032. !   "* return (char *) output_fix_trunc (insn, operands);")
  10033.   
  10034.   (define_insn ""
  10035.     [(set (match_operand:SI 0 "general_operand" "=rm")
  10036. ***************
  10037. *** 2231,2237 ****
  10038.      (clobber (match_operand:SI 3 "memory_operand" "m"))
  10039.      (clobber (match_scratch:SI 4 "=&q"))]
  10040.     "TARGET_80387"
  10041. !   "* return output_fix_trunc (insn, operands);")
  10042.   
  10043.   ;; Conversion between fixed point and floating point.
  10044.   ;; The actual pattern that matches these is at the end of this file.
  10045. --- 2010,2016 ----
  10046.      (clobber (match_operand:SI 3 "memory_operand" "m"))
  10047.      (clobber (match_scratch:SI 4 "=&q"))]
  10048.     "TARGET_80387"
  10049. !   "* return (char *) output_fix_trunc (insn, operands);")
  10050.   
  10051.   ;; Conversion between fixed point and floating point.
  10052.   ;; The actual pattern that matches these is at the end of this file.
  10053. ***************
  10054. *** 2264,2276 ****
  10055.   
  10056.   (define_expand "floatsixf2"
  10057.     [(set (match_operand:XF 0 "register_operand" "")
  10058. !     (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))]
  10059.     "TARGET_80387"
  10060.     "")
  10061.   
  10062.   (define_expand "floatdixf2"
  10063.     [(set (match_operand:XF 0 "register_operand" "")
  10064. !     (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))]
  10065.     "TARGET_80387"
  10066.     "")
  10067.   
  10068. --- 2043,2055 ----
  10069.   
  10070.   (define_expand "floatsixf2"
  10071.     [(set (match_operand:XF 0 "register_operand" "")
  10072. !       (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))]
  10073.     "TARGET_80387"
  10074.     "")
  10075.   
  10076.   (define_expand "floatdixf2"
  10077.     [(set (match_operand:XF 0 "register_operand" "")
  10078. !       (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))]
  10079.     "TARGET_80387"
  10080.     "")
  10081.   
  10082. ***************
  10083. *** 2278,2284 ****
  10084.   
  10085.   (define_insn ""
  10086.     [(set (match_operand:XF 0 "register_operand" "=f")
  10087. !     (float:XF (match_operand:DI 1 "general_operand" "rm")))]
  10088.     "TARGET_80387"
  10089.     "*
  10090.   {
  10091. --- 2057,2063 ----
  10092.   
  10093.   (define_insn ""
  10094.     [(set (match_operand:XF 0 "register_operand" "=f")
  10095. !       (float:XF (match_operand:DI 1 "general_operand" "rm")))]
  10096.     "TARGET_80387"
  10097.     "*
  10098.   {
  10099. ***************
  10100. *** 2346,2352 ****
  10101.   
  10102.   (define_insn ""
  10103.     [(set (match_operand:XF 0 "register_operand" "=f,f")
  10104. !     (float:XF (match_operand:SI 1 "general_operand" "m,!*r")))]
  10105.     "TARGET_80387"
  10106.     "*
  10107.   {
  10108. --- 2125,2131 ----
  10109.   
  10110.   (define_insn ""
  10111.     [(set (match_operand:XF 0 "register_operand" "=f,f")
  10112. !       (float:XF (match_operand:SI 1 "general_operand" "m,!*r")))]
  10113.     "TARGET_80387"
  10114.     "*
  10115.   {
  10116. ***************
  10117. *** 2381,2463 ****
  10118.   ;;- add instructions
  10119.   
  10120.   (define_insn "adddi3"
  10121. !   [(set (match_operand:DI 0 "general_operand" "=&r,ro,o,&r,ro,o,&r,o,o,o")
  10122. !     (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,o,riF,o,or,riF,riF,o")
  10123. !          (match_operand:DI 2 "general_operand" "o,riF,o,0,0,0,oriF,riF,o,o")))
  10124. !    (clobber (match_scratch:SI 3 "=X,X,&r,X,&r,&r,X,&r,&r,&r"))]
  10125.     ""
  10126.     "*
  10127.   {
  10128. !   rtx low[3], high[3], xops[7], temp;
  10129.   
  10130.     CC_STATUS_INIT;
  10131.   
  10132. -   if (rtx_equal_p (operands[0], operands[2]))
  10133. -     {
  10134. -       temp = operands[1];
  10135. -       operands[1] = operands[2];
  10136. -       operands[2] = temp;
  10137. -     }
  10138.     split_di (operands, 3, low, high);
  10139. -   if (!rtx_equal_p (operands[0], operands[1]))
  10140. -     {
  10141. -       xops[0] = high[0];
  10142. -       xops[1] = low[0];
  10143. -       xops[2] = high[1];
  10144. -       xops[3] = low[1];
  10145. -       if (GET_CODE (operands[0]) != MEM)
  10146. -     {
  10147. -       output_asm_insn (AS2 (mov%L1,%3,%1), xops);
  10148. -       output_asm_insn (AS2 (mov%L0,%2,%0), xops);
  10149. -     }
  10150. -       else
  10151. -     {
  10152. -       xops[4] = high[2];
  10153. -       xops[5] = low[2];
  10154. -       xops[6] = operands[3];
  10155. -       output_asm_insn (AS2 (mov%L6,%3,%6), xops);
  10156. -       output_asm_insn (AS2 (add%L6,%5,%6), xops);
  10157. -       output_asm_insn (AS2 (mov%L1,%6,%1), xops);
  10158. -       output_asm_insn (AS2 (mov%L6,%2,%6), xops);
  10159. -       output_asm_insn (AS2 (adc%L6,%4,%6), xops);
  10160. -       output_asm_insn (AS2 (mov%L0,%6,%0), xops);
  10161. -       RET;
  10162. -     }
  10163. -     }
  10164. -   if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
  10165. -     {
  10166. -       xops[0] = high[0];
  10167. -       xops[1] = low[0];
  10168. -       xops[2] = high[2];
  10169. -       xops[3] = low[2];
  10170. -       xops[4] = operands[3];
  10171. -       output_asm_insn (AS2 (mov%L4,%3,%4), xops);
  10172. -       output_asm_insn (AS2 (add%L1,%4,%1), xops);
  10173. -       output_asm_insn (AS2 (mov%L4,%2,%4), xops);
  10174. -       output_asm_insn (AS2 (adc%L0,%4,%0), xops);
  10175. -     }
  10176.   
  10177. !   else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
  10178.       {
  10179.         output_asm_insn (AS2 (add%L0,%2,%0), low);
  10180.         output_asm_insn (AS2 (adc%L0,%2,%0), high);
  10181.       }
  10182.     else
  10183.       output_asm_insn (AS2 (add%L0,%2,%0), high);
  10184.     RET;
  10185.   }")
  10186.   
  10187.   ;; On a 486, it is faster to do movl/addl than to do a single leal if
  10188.   ;; operands[1] and operands[2] are both registers.
  10189.   
  10190.   (define_insn "addsi3"
  10191. !   [(set (match_operand:SI 0 "general_operand" "=?r,rm,r")
  10192.       (plus:SI (match_operand:SI 1 "general_operand" "%r,0,0")
  10193.            (match_operand:SI 2 "general_operand" "ri,ri,rm")))]
  10194.     ""
  10195. --- 2160,2193 ----
  10196.   ;;- add instructions
  10197.   
  10198.   (define_insn "adddi3"
  10199. !   [(set (match_operand:DI 0 "general_operand" "=&r,ro")
  10200. !     (plus:DI (match_operand:DI 1 "general_operand" "%0,0")
  10201. !          (match_operand:DI 2 "general_operand" "o,riF")))]
  10202.     ""
  10203.     "*
  10204.   {
  10205. !   rtx low[3], high[3];
  10206.   
  10207.     CC_STATUS_INIT;
  10208.   
  10209.     split_di (operands, 3, low, high);
  10210.   
  10211. !   if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
  10212.       {
  10213.         output_asm_insn (AS2 (add%L0,%2,%0), low);
  10214.         output_asm_insn (AS2 (adc%L0,%2,%0), high);
  10215.       }
  10216.     else
  10217.       output_asm_insn (AS2 (add%L0,%2,%0), high);
  10218.     RET;
  10219.   }")
  10220.   
  10221.   ;; On a 486, it is faster to do movl/addl than to do a single leal if
  10222.   ;; operands[1] and operands[2] are both registers.
  10223.   
  10224. + ; intel1 removed ? from first constraint
  10225.   (define_insn "addsi3"
  10226. !   [(set (match_operand:SI 0 "general_operand" "=r,rm,r")
  10227.       (plus:SI (match_operand:SI 1 "general_operand" "%r,0,0")
  10228.            (match_operand:SI 2 "general_operand" "ri,ri,rm")))]
  10229.     ""
  10230. ***************
  10231. *** 2468,2487 ****
  10232.         if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
  10233.       return AS2 (add%L0,%1,%0);
  10234.   
  10235. !       if (operands[2] == stack_pointer_rtx)
  10236. !     {
  10237. !       rtx temp;
  10238.   
  10239. !       temp = operands[1];
  10240. !       operands[1] = operands[2];
  10241. !       operands[2] = temp;
  10242. !     }
  10243.   
  10244. !       if (operands[2] != stack_pointer_rtx)
  10245. !     {
  10246. !       CC_STATUS_INIT;
  10247. !       operands[1] = SET_SRC (PATTERN (insn));
  10248. !       return AS2 (lea%L0,%a1,%0);
  10249.       }
  10250.   
  10251.         output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  10252. --- 2198,2220 ----
  10253.         if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
  10254.       return AS2 (add%L0,%1,%0);
  10255.   
  10256. !       if (! (TARGET_486 || TARGET_PENTIUM) || ! REG_P (operands[2]))
  10257. !         {
  10258. !       CC_STATUS_INIT;
  10259.   
  10260. !       if (operands[2] == stack_pointer_rtx)
  10261. !         {
  10262. !           rtx temp;
  10263.   
  10264. !           temp = operands[1];
  10265. !           operands[1] = operands[2];
  10266. !           operands[2] = temp;
  10267. !         }
  10268. !       if (operands[2] != stack_pointer_rtx)
  10269. !         {
  10270. !           operands[1] = SET_SRC (PATTERN (insn));
  10271. !           return AS2 (lea%L0,%a1,%0);
  10272. !         }
  10273.       }
  10274.   
  10275.         output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  10276. ***************
  10277. *** 2512,2535 ****
  10278.         && GET_CODE (operands[2]) == CONST_INT
  10279.         && (INTVAL (operands[2]) & 0xff) == 0)
  10280.       {
  10281. -       int byteval = (INTVAL (operands[2]) >> 8) & 0xff;
  10282.         CC_STATUS_INIT;
  10283.   
  10284. !       if (byteval == 1)
  10285. !     return AS1 (inc%B0,%h0);
  10286. !       else if (byteval == 255)
  10287. !     return AS1 (dec%B0,%h0);
  10288.   
  10289. -       operands[2] = GEN_INT (byteval);
  10290.         return AS2 (add%B0,%2,%h0);
  10291.       }
  10292.   
  10293.     if (operands[2] == const1_rtx)
  10294.       return AS1 (inc%W0,%0);
  10295.   
  10296. !   if (operands[2] == constm1_rtx
  10297. !       || (GET_CODE (operands[2]) == CONST_INT
  10298. !       && INTVAL (operands[2]) == 65535))
  10299.       return AS1 (dec%W0,%0);
  10300.   
  10301.     return AS2 (add%W0,%2,%0);
  10302. --- 2245,2267 ----
  10303.         && GET_CODE (operands[2]) == CONST_INT
  10304.         && (INTVAL (operands[2]) & 0xff) == 0)
  10305.       {
  10306.         CC_STATUS_INIT;
  10307.   
  10308. !        operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  10309. !       if (operands[2] == const1_rtx)
  10310. !       return AS1 (inc%B0,%h0);
  10311. !       if (operands[2] == constm1_rtx)
  10312. !       return AS1 (dec%B0,%h0);
  10313.   
  10314.         return AS2 (add%B0,%2,%h0);
  10315.       }
  10316.   
  10317.     if (operands[2] == const1_rtx)
  10318.       return AS1 (inc%W0,%0);
  10319.   
  10320. !   if (operands[2] == constm1_rtx)
  10321.       return AS1 (dec%W0,%0);
  10322.   
  10323.     return AS2 (add%W0,%2,%0);
  10324. ***************
  10325. *** 2545,2553 ****
  10326.     if (operands[2] == const1_rtx)
  10327.       return AS1 (inc%B0,%0);
  10328.   
  10329. !   if (operands[2] == constm1_rtx
  10330. !       || (GET_CODE (operands[2]) == CONST_INT
  10331. !       && INTVAL (operands[2]) == 255))
  10332.       return AS1 (dec%B0,%0);
  10333.   
  10334.     return AS2 (add%B0,%2,%0);
  10335. --- 2277,2283 ----
  10336.     if (operands[2] == const1_rtx)
  10337.       return AS1 (inc%B0,%0);
  10338.   
  10339. !   if (operands[2] == constm1_rtx)
  10340.       return AS1 (dec%B0,%0);
  10341.   
  10342.     return AS2 (add%B0,%2,%0);
  10343. ***************
  10344. *** 2580,2586 ****
  10345.   
  10346.   ;; addsi3 is faster, so put this after.
  10347.   
  10348. ! (define_insn "movsi_lea"
  10349.     [(set (match_operand:SI 0 "register_operand" "=r")
  10350.           (match_operand:QI 1 "address_operand" "p"))]
  10351.     ""
  10352. --- 2310,2316 ----
  10353.   
  10354.   ;; addsi3 is faster, so put this after.
  10355.   
  10356. ! (define_insn ""
  10357.     [(set (match_operand:SI 0 "register_operand" "=r")
  10358.           (match_operand:QI 1 "address_operand" "p"))]
  10359.     ""
  10360. ***************
  10361. *** 2610,2617 ****
  10362.   
  10363.   (define_expand "addxf3"
  10364.     [(set (match_operand:XF 0 "register_operand" "")
  10365. !     (plus:XF (match_operand:XF 1 "nonimmediate_operand" "")
  10366. !          (match_operand:XF 2 "nonimmediate_operand" "")))]
  10367.     "TARGET_80387"
  10368.     "")
  10369.   
  10370. --- 2340,2347 ----
  10371.   
  10372.   (define_expand "addxf3"
  10373.     [(set (match_operand:XF 0 "register_operand" "")
  10374. !       (plus:XF (match_operand:XF 1 "nonimmediate_operand" "")
  10375. !                (match_operand:XF 2 "nonimmediate_operand" "")))]
  10376.     "TARGET_80387"
  10377.     "")
  10378.   
  10379. ***************
  10380. *** 2632,2697 ****
  10381.   ;;- subtract instructions
  10382.   
  10383.   (define_insn "subdi3"
  10384. !   [(set (match_operand:DI 0 "general_operand" "=&r,ro,&r,o,o")
  10385. !     (minus:DI (match_operand:DI 1 "general_operand" "0,0,roiF,riF,o")
  10386. !           (match_operand:DI 2 "general_operand" "o,riF,roiF,riF,o")))
  10387. !    (clobber (match_scratch:SI 3 "=X,X,X,&r,&r"))]
  10388.     ""
  10389.     "*
  10390.   {
  10391. !   rtx low[3], high[3], xops[7];
  10392.   
  10393.     CC_STATUS_INIT;
  10394.   
  10395.     split_di (operands, 3, low, high);
  10396.   
  10397. !   if (!rtx_equal_p (operands[0], operands[1]))
  10398. !     {
  10399. !       xops[0] = high[0];
  10400. !       xops[1] = low[0];
  10401. !       xops[2] = high[1];
  10402. !       xops[3] = low[1];
  10403. !       if (GET_CODE (operands[0]) != MEM)
  10404. !     {
  10405. !       output_asm_insn (AS2 (mov%L1,%3,%1), xops);
  10406. !       output_asm_insn (AS2 (mov%L0,%2,%0), xops);
  10407. !     }
  10408. !       else
  10409. !     {
  10410. !       xops[4] = high[2];
  10411. !       xops[5] = low[2];
  10412. !       xops[6] = operands[3];
  10413. !       output_asm_insn (AS2 (mov%L6,%3,%6), xops);
  10414. !       output_asm_insn (AS2 (sub%L6,%5,%6), xops);
  10415. !       output_asm_insn (AS2 (mov%L1,%6,%1), xops);
  10416. !       output_asm_insn (AS2 (mov%L6,%2,%6), xops);
  10417. !       output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
  10418. !       output_asm_insn (AS2 (mov%L0,%6,%0), xops);
  10419. !       RET;
  10420. !     }
  10421. !     }
  10422. !   if (GET_CODE (operands[3]) == REG)
  10423. !     {
  10424. !       xops[0] = high[0];
  10425. !       xops[1] = low[0];
  10426. !       xops[2] = high[2];
  10427. !       xops[3] = low[2];
  10428. !       xops[4] = operands[3];
  10429. !       output_asm_insn (AS2 (mov%L4,%3,%4), xops);
  10430. !       output_asm_insn (AS2 (sub%L1,%4,%1), xops);
  10431. !       output_asm_insn (AS2 (mov%L4,%2,%4), xops);
  10432. !       output_asm_insn (AS2 (sbb%L0,%4,%0), xops);
  10433. !     }
  10434. !   else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
  10435.       {
  10436.         output_asm_insn (AS2 (sub%L0,%2,%0), low);
  10437.         output_asm_insn (AS2 (sbb%L0,%2,%0), high);
  10438.       }
  10439.     else
  10440.       output_asm_insn (AS2 (sub%L0,%2,%0), high);
  10441.   
  10442. --- 2362,2384 ----
  10443.   ;;- subtract instructions
  10444.   
  10445.   (define_insn "subdi3"
  10446. !   [(set (match_operand:DI 0 "general_operand" "=&r,ro")
  10447. !     (minus:DI (match_operand:DI 1 "general_operand" "0,0")
  10448. !           (match_operand:DI 2 "general_operand" "o,riF")))]
  10449.     ""
  10450.     "*
  10451.   {
  10452. !   rtx low[3], high[3];
  10453.   
  10454.     CC_STATUS_INIT;
  10455.   
  10456.     split_di (operands, 3, low, high);
  10457.   
  10458. !   if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
  10459.       {
  10460.         output_asm_insn (AS2 (sub%L0,%2,%0), low);
  10461.         output_asm_insn (AS2 (sbb%L0,%2,%0), high);
  10462.       }
  10463.     else
  10464.       output_asm_insn (AS2 (sub%L0,%2,%0), high);
  10465.   
  10466. ***************
  10467. *** 2723,2730 ****
  10468.   
  10469.   (define_expand "subxf3"
  10470.     [(set (match_operand:XF 0 "register_operand" "")
  10471. !     (minus:XF (match_operand:XF 1 "nonimmediate_operand" "")
  10472. !           (match_operand:XF 2 "nonimmediate_operand" "")))]
  10473.     "TARGET_80387"
  10474.     "")
  10475.   
  10476. --- 2410,2417 ----
  10477.   
  10478.   (define_expand "subxf3"
  10479.     [(set (match_operand:XF 0 "register_operand" "")
  10480. !       (minus:XF (match_operand:XF 1 "nonimmediate_operand" "")
  10481. !                 (match_operand:XF 2 "nonimmediate_operand" "")))]
  10482.     "TARGET_80387"
  10483.     "")
  10484.   
  10485. ***************
  10486. *** 2753,2766 ****
  10487.   
  10488.   (define_insn ""
  10489.     [(set (match_operand:HI 0 "general_operand" "=r")
  10490. !     (mult:HI (match_operand:HI 1 "general_operand" "%0")
  10491.            (match_operand:HI 2 "general_operand" "r")))]
  10492.     "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80"
  10493.     "* return AS2 (imul%W0,%2,%0);")
  10494.   
  10495.   (define_insn "mulhi3"
  10496.     [(set (match_operand:HI 0 "general_operand" "=r,r")
  10497. !     (mult:HI (match_operand:HI 1 "general_operand" "%0,rm")
  10498.            (match_operand:HI 2 "general_operand" "g,i")))]
  10499.     ""
  10500.     "*
  10501. --- 2440,2453 ----
  10502.   
  10503.   (define_insn ""
  10504.     [(set (match_operand:HI 0 "general_operand" "=r")
  10505. !     (mult:SI (match_operand:HI 1 "general_operand" "%0")
  10506.            (match_operand:HI 2 "general_operand" "r")))]
  10507.     "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80"
  10508.     "* return AS2 (imul%W0,%2,%0);")
  10509.   
  10510.   (define_insn "mulhi3"
  10511.     [(set (match_operand:HI 0 "general_operand" "=r,r")
  10512. !     (mult:SI (match_operand:HI 1 "general_operand" "%0,rm")
  10513.            (match_operand:HI 2 "general_operand" "g,i")))]
  10514.     ""
  10515.     "*
  10516. ***************
  10517. *** 2795,2852 ****
  10518.     return AS3 (imul%L0,%2,%1,%0);
  10519.   }")
  10520.   
  10521. ! (define_insn "umulqihi3"
  10522.     [(set (match_operand:HI 0 "general_operand" "=a")
  10523. !     (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
  10524. !          (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
  10525.     ""
  10526.     "mul%B0 %2")
  10527.   
  10528. - (define_insn "mulqihi3"
  10529. -   [(set (match_operand:HI 0 "general_operand" "=a")
  10530. -     (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
  10531. -          (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
  10532. -   ""
  10533. -   "imul%B0 %2")
  10534. - (define_insn "umulsidi3"
  10535. -   [(set (match_operand:DI 0 "register_operand" "=A")
  10536. -     (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
  10537. -          (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
  10538. -   "TARGET_WIDE_MULTIPLY"
  10539. -   "mul%L0 %2")
  10540. - (define_insn "mulsidi3"
  10541. -   [(set (match_operand:DI 0 "register_operand" "=A")
  10542. -     (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
  10543. -          (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
  10544. -   "TARGET_WIDE_MULTIPLY"
  10545. -   "imul%L0 %2")
  10546. - (define_insn "umulsi3_highpart"
  10547. -   [(set (match_operand:SI 0 "register_operand" "=d")
  10548. -     (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a"))
  10549. -                        (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
  10550. -                   (const_int 32))))
  10551. -    (clobber (match_scratch:SI 3 "=a"))]
  10552. -   "TARGET_WIDE_MULTIPLY"
  10553. -   "mul%L0 %2")
  10554. - (define_insn "smulsi3_highpart"
  10555. -   [(set (match_operand:SI 0 "register_operand" "=d")
  10556. -     (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%a"))
  10557. -                        (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
  10558. -                   (const_int 32))))
  10559. -    (clobber (match_scratch:SI 3 "=a"))]
  10560. -   "TARGET_WIDE_MULTIPLY"
  10561. -   "imul%L0 %2")
  10562.   ;; The patterns that match these are at the end of this file.
  10563.   
  10564.   (define_expand "mulxf3"
  10565.     [(set (match_operand:XF 0 "register_operand" "")
  10566. !     (mult:XF (match_operand:XF 1 "nonimmediate_operand" "")
  10567. !          (match_operand:XF 2 "nonimmediate_operand" "")))]
  10568.     "TARGET_80387"
  10569.     "")
  10570.   
  10571. --- 2482,2502 ----
  10572.     return AS3 (imul%L0,%2,%1,%0);
  10573.   }")
  10574.   
  10575. ! (define_insn ""
  10576.     [(set (match_operand:HI 0 "general_operand" "=a")
  10577. !     (mult:SI (zero_extend:HI
  10578. !           (match_operand:QI 1 "nonimmediate_operand" "%0"))
  10579. !          (zero_extend:HI
  10580. !           (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
  10581.     ""
  10582.     "mul%B0 %2")
  10583.   
  10584.   ;; The patterns that match these are at the end of this file.
  10585.   
  10586.   (define_expand "mulxf3"
  10587.     [(set (match_operand:XF 0 "register_operand" "")
  10588. !       (mult:XF (match_operand:XF 1 "nonimmediate_operand" "")
  10589. !                (match_operand:XF 2 "nonimmediate_operand" "")))]
  10590.     "TARGET_80387"
  10591.     "")
  10592.   
  10593. ***************
  10594. *** 2884,2891 ****
  10595.   
  10596.   (define_expand "divxf3"
  10597.     [(set (match_operand:XF 0 "register_operand" "")
  10598. !     (div:XF (match_operand:XF 1 "nonimmediate_operand" "")
  10599. !         (match_operand:XF 2 "nonimmediate_operand" "")))]
  10600.     "TARGET_80387"
  10601.     "")
  10602.   
  10603. --- 2534,2541 ----
  10604.   
  10605.   (define_expand "divxf3"
  10606.     [(set (match_operand:XF 0 "register_operand" "")
  10607. !       (div:XF (match_operand:XF 1 "nonimmediate_operand" "")
  10608. !               (match_operand:XF 2 "nonimmediate_operand" "")))]
  10609.     "TARGET_80387"
  10610.     "")
  10611.   
  10612. ***************
  10613. *** 2990,3009 ****
  10614.   ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
  10615.   
  10616.   ;; ??? What if we only change one byte of an offsettable memory reference?
  10617.   (define_insn "andsi3"
  10618. !   [(set (match_operand:SI 0 "general_operand" "=r,r,rm,r")
  10619. !     (and:SI (match_operand:SI 1 "general_operand" "%rm,qm,0,0")
  10620. !         (match_operand:SI 2 "general_operand" "L,K,ri,rm")))]
  10621.     ""
  10622.     "*
  10623.   {
  10624.     if (GET_CODE (operands[2]) == CONST_INT
  10625.         && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  10626.       {
  10627.         if (INTVAL (operands[2]) == 0xffff && REG_P (operands[0])
  10628.         && (! REG_P (operands[1])
  10629.             || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
  10630. !       && (TARGET_386 || ! rtx_equal_p (operands[0], operands[1])))
  10631.       {
  10632.         /* ??? tege: Should forget CC_STATUS only if we clobber a
  10633.            remembered operand.  Fix that later.  */
  10634. --- 2640,2676 ----
  10635.   ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
  10636.   
  10637.   ;; ??? What if we only change one byte of an offsettable memory reference?
  10638. + ;;(define_insn "andsi3"
  10639. + ;;  [(set (match_operand:SI 0 "general_operand" "=r,r,rm,r")
  10640. + ;;    (and:SI (match_operand:SI 1 "general_operand" "%rm,qm,0,0")
  10641. + ;;        (match_operand:SI 2 "general_operand" "L,K,ri,rm")))]
  10642. + ;;  ""
  10643. + ;;  "*
  10644. + ;;{
  10645. + ;intel1
  10646.   (define_insn "andsi3"
  10647. !   [(set (match_operand:SI 0 "general_operand" "=rm,r,r")
  10648. !     (and:SI (match_operand:SI 1 "general_operand" "0,0,rm")
  10649. !         (match_operand:SI 2 "general_operand" "ri,rm,0")))]
  10650.     ""
  10651.     "*
  10652.   {
  10653. +   /* intel1 */
  10654. +   if (!rtx_equal_p (operands[0], operands[1])
  10655. +       && rtx_equal_p (operands[0], operands[2]))
  10656. +     {
  10657. +       rtx tmp;
  10658. +       tmp = operands[1];
  10659. +       operands[1] = operands[2];
  10660. +       operands[2] = tmp;
  10661. +     }
  10662.     if (GET_CODE (operands[2]) == CONST_INT
  10663.         && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  10664.       {
  10665.         if (INTVAL (operands[2]) == 0xffff && REG_P (operands[0])
  10666.         && (! REG_P (operands[1])
  10667.             || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
  10668. !       && (! (TARGET_486 || TARGET_PENTIUM) || ! rtx_equal_p (operands[0], operands[1])))
  10669.       {
  10670.         /* ??? tege: Should forget CC_STATUS only if we clobber a
  10671.            remembered operand.  Fix that later.  */
  10672. ***************
  10673. *** 3019,3025 ****
  10674.         && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
  10675.         && (! REG_P (operands[1])
  10676.             || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
  10677. !       && (TARGET_386 || ! rtx_equal_p (operands[0], operands[1])))
  10678.       {
  10679.         /* ??? tege: Should forget CC_STATUS only if we clobber a
  10680.            remembered operand.  Fix that later.  */
  10681. --- 2686,2692 ----
  10682.         && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
  10683.         && (! REG_P (operands[1])
  10684.             || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
  10685. !       && (! (TARGET_486 || TARGET_PENTIUM) || ! rtx_equal_p (operands[0], operands[1])))
  10686.       {
  10687.         /* ??? tege: Should forget CC_STATUS only if we clobber a
  10688.            remembered operand.  Fix that later.  */
  10689. ***************
  10690. *** 3148,3161 ****
  10691.   
  10692.   ;;- Bit set (inclusive or) instructions
  10693.   
  10694.   ;; ??? What if we only change one byte of an offsettable memory reference?
  10695.   (define_insn "iorsi3"
  10696. !   [(set (match_operand:SI 0 "general_operand" "=rm,r")
  10697. !     (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
  10698. !         (match_operand:SI 2 "general_operand" "ri,rm")))]
  10699.     ""
  10700.     "*
  10701.   {
  10702.     if (GET_CODE (operands[2]) == CONST_INT
  10703.         && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  10704.       {
  10705. --- 2815,2837 ----
  10706.   
  10707.   ;;- Bit set (inclusive or) instructions
  10708.   
  10709. + ;intel1 added last constaints
  10710.   ;; ??? What if we only change one byte of an offsettable memory reference?
  10711.   (define_insn "iorsi3"
  10712. !   [(set (match_operand:SI 0 "general_operand" "=rm,r,r")
  10713. !     (ior:SI (match_operand:SI 1 "general_operand" "%0,0,rm")
  10714. !         (match_operand:SI 2 "general_operand" "ri,rm,0")))]
  10715.     ""
  10716.     "*
  10717.   {
  10718. +   /* intel1 */
  10719. +   if (!rtx_equal_p (operands[0], operands[1]))
  10720. +     {
  10721. +       rtx tmp;
  10722. +       tmp = operands[1];
  10723. +       operands[1] = operands[2];
  10724. +       operands[2] = tmp;
  10725. +     }
  10726.     if (GET_CODE (operands[2]) == CONST_INT
  10727.         && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  10728.       {
  10729. ***************
  10730. *** 3185,3197 ****
  10731.     return AS2 (or%L0,%2,%0);
  10732.   }")
  10733.   
  10734.   (define_insn "iorhi3"
  10735. !   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  10736. !     (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
  10737. !         (match_operand:HI 2 "general_operand" "ri,rm")))]
  10738.     ""
  10739.     "*
  10740.   {
  10741.     if (GET_CODE (operands[2]) == CONST_INT
  10742.         && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  10743.       {
  10744. --- 2861,2882 ----
  10745.     return AS2 (or%L0,%2,%0);
  10746.   }")
  10747.   
  10748. + ;intel1 added last constraint
  10749.   (define_insn "iorhi3"
  10750. !   [(set (match_operand:HI 0 "general_operand" "=rm,r,r")
  10751. !     (ior:HI (match_operand:HI 1 "general_operand" "%0,0,rm")
  10752. !         (match_operand:HI 2 "general_operand" "ri,rm,0")))]
  10753.     ""
  10754.     "*
  10755.   {
  10756. +   /* intel1 */
  10757. +   if (!rtx_equal_p (operands[0], operands[1]))
  10758. +     {
  10759. +       rtx tmp;
  10760. +       tmp = operands[1];
  10761. +       operands[1] = operands[2];
  10762. +       operands[2] = tmp;
  10763. +     }
  10764.     if (GET_CODE (operands[2]) == CONST_INT
  10765.         && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  10766.       {
  10767. ***************
  10768. *** 3227,3238 ****
  10769.     return AS2 (or%W0,%2,%0);
  10770.   }")
  10771.   
  10772.   (define_insn "iorqi3"
  10773. !   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  10774. !     (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
  10775. !         (match_operand:QI 2 "general_operand" "qn,qmn")))]
  10776.     ""
  10777. !   "* return AS2 (or%B0,%2,%0);")
  10778.   
  10779.   ;;- xor instructions
  10780.   
  10781. --- 2912,2935 ----
  10782.     return AS2 (or%W0,%2,%0);
  10783.   }")
  10784.   
  10785. + ;intel1 added last constraint 
  10786.   (define_insn "iorqi3"
  10787. !   [(set (match_operand:QI 0 "general_operand" "=qm,q,q")
  10788. !     (ior:QI (match_operand:QI 1 "general_operand" "%0,0,qm")
  10789. !         (match_operand:QI 2 "general_operand" "qn,qmn,0")))]
  10790.     ""
  10791. !   "* 
  10792. ! {
  10793. !   /* intel1 */
  10794. !   if (!rtx_equal_p (operands[0], operands[1]))
  10795. !     {
  10796. !       rtx tmp;
  10797. !       tmp = operands[1];
  10798. !       operands[1] = operands[2];
  10799. !       operands[2] = tmp;
  10800. !     }
  10801. !   return AS2 (or%B0,%2,%0);
  10802. ! }")
  10803.   
  10804.   ;;- xor instructions
  10805.   
  10806. ***************
  10807. *** 3273,3285 ****
  10808.     return AS2 (xor%L0,%2,%0);
  10809.   }")
  10810.   
  10811.   (define_insn "xorhi3"
  10812. !   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  10813. !     (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
  10814. !         (match_operand:HI 2 "general_operand" "ri,rm")))]
  10815.     ""
  10816.     "*
  10817.   {
  10818.     if (GET_CODE (operands[2]) == CONST_INT
  10819.         && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  10820.       {
  10821. --- 2970,2991 ----
  10822.     return AS2 (xor%L0,%2,%0);
  10823.   }")
  10824.   
  10825. + ;intel1 added last constraint 
  10826.   (define_insn "xorhi3"
  10827. !   [(set (match_operand:HI 0 "general_operand" "=rm,r,r")
  10828. !     (xor:HI (match_operand:HI 1 "general_operand" "%0,0,rm")
  10829. !         (match_operand:HI 2 "general_operand" "ri,rm,0")))]
  10830.     ""
  10831.     "*
  10832.   {
  10833. +   /* intel1 */
  10834. +   if (!rtx_equal_p (operands[0], operands[1]))
  10835. +     {
  10836. +       rtx tmp;
  10837. +       tmp = operands[1];
  10838. +       operands[1] = operands[2];
  10839. +       operands[2] = tmp;
  10840. +     }
  10841.     if (GET_CODE (operands[2]) == CONST_INT
  10842.         && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  10843.       {
  10844. ***************
  10845. *** 3315,3326 ****
  10846.     return AS2 (xor%W0,%2,%0);
  10847.   }")
  10848.   
  10849.   (define_insn "xorqi3"
  10850. !   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  10851. !     (xor:QI (match_operand:QI 1 "general_operand" "%0,0")
  10852. !         (match_operand:QI 2 "general_operand" "qn,qm")))]
  10853. !   ""
  10854. !   "* return AS2 (xor%B0,%2,%0);")
  10855.   
  10856.   ;;- negation instructions
  10857.   
  10858. --- 3021,3044 ----
  10859.     return AS2 (xor%W0,%2,%0);
  10860.   }")
  10861.   
  10862. + ;intel1 added last constraint 
  10863.   (define_insn "xorqi3"
  10864. !   [(set (match_operand:QI 0 "general_operand" "=qm,q,q")
  10865. !     (xor:QI (match_operand:QI 1 "general_operand" "%0,0,qm")
  10866. !         (match_operand:QI 2 "general_operand" "qn,qm,0")))]
  10867. !   ""
  10868. !   "* 
  10869. !  {
  10870. !   /* intel1 */
  10871. !   if (!rtx_equal_p (operands[0], operands[1]))
  10872. !     {
  10873. !       rtx tmp;
  10874. !       tmp = operands[1];
  10875. !       operands[1] = operands[2];
  10876. !       operands[2] = tmp;
  10877. !     }
  10878. !  return AS2 (xor%B0,%2,%0);
  10879. !  }")
  10880.   
  10881.   ;;- negation instructions
  10882.   
  10883. ***************
  10884. *** 3382,3394 ****
  10885.   
  10886.   (define_insn "negxf2"
  10887.     [(set (match_operand:XF 0 "register_operand" "=f")
  10888. !     (neg:XF (match_operand:XF 1 "general_operand" "0")))]
  10889.     "TARGET_80387"
  10890.     "fchs")
  10891.   
  10892.   (define_insn ""
  10893.     [(set (match_operand:XF 0 "register_operand" "=f")
  10894. !     (neg:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
  10895.     "TARGET_80387"
  10896.     "fchs")
  10897.   
  10898. --- 3100,3112 ----
  10899.   
  10900.   (define_insn "negxf2"
  10901.     [(set (match_operand:XF 0 "register_operand" "=f")
  10902. !       (neg:XF (match_operand:XF 1 "general_operand" "0")))]
  10903.     "TARGET_80387"
  10904.     "fchs")
  10905.   
  10906.   (define_insn ""
  10907.     [(set (match_operand:XF 0 "register_operand" "=f")
  10908. !       (neg:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
  10909.     "TARGET_80387"
  10910.     "fchs")
  10911.   
  10912. ***************
  10913. *** 3398,3530 ****
  10914.     [(set (match_operand:SF 0 "register_operand" "=f")
  10915.       (abs:SF (match_operand:SF 1 "general_operand" "0")))]
  10916.     "TARGET_80387"
  10917. !   "fabs")
  10918.   
  10919.   (define_insn "absdf2"
  10920.     [(set (match_operand:DF 0 "register_operand" "=f")
  10921.       (abs:DF (match_operand:DF 1 "general_operand" "0")))]
  10922.     "TARGET_80387"
  10923. !   "fabs")
  10924.   
  10925.   (define_insn ""
  10926.     [(set (match_operand:DF 0 "register_operand" "=f")
  10927.       (abs:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]
  10928.     "TARGET_80387"
  10929. !   "fabs")
  10930.   
  10931.   (define_insn "absxf2"
  10932.     [(set (match_operand:XF 0 "register_operand" "=f")
  10933. !     (abs:XF (match_operand:XF 1 "general_operand" "0")))]
  10934.     "TARGET_80387"
  10935. !   "fabs")
  10936.   
  10937.   (define_insn ""
  10938.     [(set (match_operand:XF 0 "register_operand" "=f")
  10939. !     (abs:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
  10940.     "TARGET_80387"
  10941. !   "fabs")
  10942.   
  10943.   (define_insn "sqrtsf2"
  10944.     [(set (match_operand:SF 0 "register_operand" "=f")
  10945.       (sqrt:SF (match_operand:SF 1 "general_operand" "0")))]
  10946. !   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
  10947. !    && (TARGET_IEEE_FP || flag_fast_math) "
  10948. !   "fsqrt")
  10949.   
  10950.   (define_insn "sqrtdf2"
  10951.     [(set (match_operand:DF 0 "register_operand" "=f")
  10952.       (sqrt:DF (match_operand:DF 1 "general_operand" "0")))]
  10953. !   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
  10954. !    && (TARGET_IEEE_FP || flag_fast_math) "
  10955. !   "fsqrt")
  10956.   
  10957.   (define_insn ""
  10958.     [(set (match_operand:DF 0 "register_operand" "=f")
  10959.       (sqrt:DF (float_extend:DF
  10960.             (match_operand:SF 1 "general_operand" "0"))))]
  10961. !   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  10962. !    && (TARGET_IEEE_FP || flag_fast_math) "
  10963. !   "fsqrt")
  10964.   
  10965.   (define_insn "sqrtxf2"
  10966.     [(set (match_operand:XF 0 "register_operand" "=f")
  10967. !     (sqrt:XF (match_operand:XF 1 "general_operand" "0")))]
  10968. !   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  10969. !    && (TARGET_IEEE_FP || flag_fast_math) "
  10970. !   "fsqrt")
  10971.   
  10972.   (define_insn ""
  10973.     [(set (match_operand:XF 0 "register_operand" "=f")
  10974. !     (sqrt:XF (float_extend:XF
  10975. !           (match_operand:DF 1 "general_operand" "0"))))]
  10976. !   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  10977. !    && (TARGET_IEEE_FP || flag_fast_math) "
  10978. !   "fsqrt")
  10979.   
  10980.   (define_insn ""
  10981.     [(set (match_operand:XF 0 "register_operand" "=f")
  10982. !     (sqrt:XF (float_extend:XF
  10983. !           (match_operand:SF 1 "general_operand" "0"))))]
  10984. !   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  10985. !    && (TARGET_IEEE_FP || flag_fast_math) "
  10986. !   "fsqrt")
  10987.   
  10988.   (define_insn "sindf2"
  10989.     [(set (match_operand:DF 0 "register_operand" "=f")
  10990.       (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
  10991. !   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  10992. !    && (TARGET_IEEE_FP || flag_fast_math) "
  10993. !   "fsin")
  10994.   
  10995.   (define_insn "sinsf2"
  10996.     [(set (match_operand:SF 0 "register_operand" "=f")
  10997.       (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
  10998. !   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  10999. !    && (TARGET_IEEE_FP || flag_fast_math) "
  11000. !   "fsin")
  11001.   
  11002.   (define_insn ""
  11003.     [(set (match_operand:DF 0 "register_operand" "=f")
  11004.       (unspec:DF [(float_extend:DF
  11005.                (match_operand:SF 1 "register_operand" "0"))] 1))]
  11006. !   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  11007. !    && (TARGET_IEEE_FP || flag_fast_math) "
  11008. !   "fsin")
  11009.   
  11010.   (define_insn "sinxf2"
  11011.     [(set (match_operand:XF 0 "register_operand" "=f")
  11012.       (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
  11013. !   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  11014. !    && (TARGET_IEEE_FP || flag_fast_math) "
  11015.     "fsin")
  11016.   
  11017.   (define_insn "cosdf2"
  11018.     [(set (match_operand:DF 0 "register_operand" "=f")
  11019.       (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
  11020. !   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  11021. !    && (TARGET_IEEE_FP || flag_fast_math) "
  11022. !   "fcos")
  11023.   
  11024.   (define_insn "cossf2"
  11025.     [(set (match_operand:SF 0 "register_operand" "=f")
  11026.       (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
  11027. !   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  11028. !    && (TARGET_IEEE_FP || flag_fast_math) "
  11029. !   "fcos")
  11030.   
  11031.   (define_insn ""
  11032.     [(set (match_operand:DF 0 "register_operand" "=f")
  11033.       (unspec:DF [(float_extend:DF
  11034.                (match_operand:SF 1 "register_operand" "0"))] 2))]
  11035. !   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  11036. !    && (TARGET_IEEE_FP || flag_fast_math) "
  11037. !   "fcos")
  11038.   
  11039.   (define_insn "cosxf2"
  11040.     [(set (match_operand:XF 0 "register_operand" "=f")
  11041.       (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
  11042. !   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  11043. !    && (TARGET_IEEE_FP || flag_fast_math) "
  11044.     "fcos")
  11045.   
  11046.   ;;- one complement instructions
  11047. --- 3116,3234 ----
  11048.     [(set (match_operand:SF 0 "register_operand" "=f")
  11049.       (abs:SF (match_operand:SF 1 "general_operand" "0")))]
  11050.     "TARGET_80387"
  11051. !   "fabs"[(set_attr "type" "fpop")])
  11052.   
  11053.   (define_insn "absdf2"
  11054.     [(set (match_operand:DF 0 "register_operand" "=f")
  11055.       (abs:DF (match_operand:DF 1 "general_operand" "0")))]
  11056.     "TARGET_80387"
  11057. !   "fabs"[(set_attr "type" "fpop")])
  11058.   
  11059.   (define_insn ""
  11060.     [(set (match_operand:DF 0 "register_operand" "=f")
  11061.       (abs:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]
  11062.     "TARGET_80387"
  11063. !   "fabs"[(set_attr "type" "fpop")])
  11064.   
  11065.   (define_insn "absxf2"
  11066.     [(set (match_operand:XF 0 "register_operand" "=f")
  11067. !       (abs:XF (match_operand:XF 1 "general_operand" "0")))]
  11068.     "TARGET_80387"
  11069. !   "fabs"[(set_attr "type" "fpop")])
  11070.   
  11071.   (define_insn ""
  11072.     [(set (match_operand:XF 0 "register_operand" "=f")
  11073. !       (abs:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
  11074.     "TARGET_80387"
  11075. !   "fabs"[(set_attr "type" "fpop")])
  11076.   
  11077.   (define_insn "sqrtsf2"
  11078.     [(set (match_operand:SF 0 "register_operand" "=f")
  11079.       (sqrt:SF (match_operand:SF 1 "general_operand" "0")))]
  11080. !   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  11081. !   "fsqrt"[(set_attr "type" "fpop")])
  11082.   
  11083.   (define_insn "sqrtdf2"
  11084.     [(set (match_operand:DF 0 "register_operand" "=f")
  11085.       (sqrt:DF (match_operand:DF 1 "general_operand" "0")))]
  11086. !   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  11087. !   "fsqrt"[(set_attr "type" "fpop")])
  11088.   
  11089.   (define_insn ""
  11090.     [(set (match_operand:DF 0 "register_operand" "=f")
  11091.       (sqrt:DF (float_extend:DF
  11092.             (match_operand:SF 1 "general_operand" "0"))))]
  11093. !   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  11094. !   "fsqrt"[(set_attr "type" "fpop")])
  11095.   
  11096.   (define_insn "sqrtxf2"
  11097.     [(set (match_operand:XF 0 "register_operand" "=f")
  11098. !       (sqrt:XF (match_operand:XF 1 "general_operand" "0")))]
  11099. !   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  11100. !   "fsqrt"[(set_attr "type" "fpop")])
  11101.   
  11102.   (define_insn ""
  11103.     [(set (match_operand:XF 0 "register_operand" "=f")
  11104. !       (sqrt:XF (float_extend:XF
  11105. !                 (match_operand:DF 1 "general_operand" "0"))))]
  11106. !   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  11107. !   "fsqrt"[(set_attr "type" "fpop")])
  11108.   
  11109.   (define_insn ""
  11110.     [(set (match_operand:XF 0 "register_operand" "=f")
  11111. !       (sqrt:XF (float_extend:XF
  11112. !                 (match_operand:SF 1 "general_operand" "0"))))]
  11113. !   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  11114. !   "fsqrt"[(set_attr "type" "fpop")])
  11115.   
  11116.   (define_insn "sindf2"
  11117.     [(set (match_operand:DF 0 "register_operand" "=f")
  11118.       (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
  11119. !   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  11120. !   "fsin"[(set_attr "type" "fpop")])
  11121.   
  11122.   (define_insn "sinsf2"
  11123.     [(set (match_operand:SF 0 "register_operand" "=f")
  11124.       (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
  11125. !   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  11126. !   "fsin"[(set_attr "type" "fpop")])
  11127.   
  11128.   (define_insn ""
  11129.     [(set (match_operand:DF 0 "register_operand" "=f")
  11130.       (unspec:DF [(float_extend:DF
  11131.                (match_operand:SF 1 "register_operand" "0"))] 1))]
  11132. !   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  11133. !   "fsin"[(set_attr "type" "fpop")])
  11134.   
  11135.   (define_insn "sinxf2"
  11136.     [(set (match_operand:XF 0 "register_operand" "=f")
  11137.       (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
  11138. !   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  11139.     "fsin")
  11140.   
  11141.   (define_insn "cosdf2"
  11142.     [(set (match_operand:DF 0 "register_operand" "=f")
  11143.       (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
  11144. !   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  11145. !   "fcos"[(set_attr "type" "fpop")])
  11146.   
  11147.   (define_insn "cossf2"
  11148.     [(set (match_operand:SF 0 "register_operand" "=f")
  11149.       (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
  11150. !   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  11151. !   "fcos"[(set_attr "type" "fpop")])
  11152.   
  11153.   (define_insn ""
  11154.     [(set (match_operand:DF 0 "register_operand" "=f")
  11155.       (unspec:DF [(float_extend:DF
  11156.                (match_operand:SF 1 "register_operand" "0"))] 2))]
  11157. !   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  11158. !   "fcos"[(set_attr "type" "fpop")])
  11159.   
  11160.   (define_insn "cosxf2"
  11161.     [(set (match_operand:XF 0 "register_operand" "=f")
  11162.       (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
  11163. !   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  11164.     "fcos")
  11165.   
  11166.   ;;- one complement instructions
  11167. ***************
  11168. *** 3676,3682 ****
  11169.   {
  11170.     if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
  11171.       {
  11172. !       if (!TARGET_386 && INTVAL (operands[2]) == 1)
  11173.       {
  11174.         output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  11175.         return AS2 (add%L0,%1,%0);
  11176. --- 3380,3386 ----
  11177.   {
  11178.     if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
  11179.       {
  11180. !       if ((TARGET_486 || TARGET_PENTIUM) && INTVAL (operands[2]) == 1)
  11181.       {
  11182.         output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  11183.         return AS2 (add%L0,%1,%0);
  11184. ***************
  11185. *** 4177,4183 ****
  11186.                (const_int 1)
  11187.                (match_operand:SI 2 "general_operand" "r"))
  11188.       (match_operand:SI 3 "const_int_operand" "n"))]
  11189. !   "TARGET_386 && GET_CODE (operands[2]) != CONST_INT"
  11190.     "*
  11191.   {
  11192.     CC_STATUS_INIT;
  11193. --- 3881,3887 ----
  11194.                (const_int 1)
  11195.                (match_operand:SI 2 "general_operand" "r"))
  11196.       (match_operand:SI 3 "const_int_operand" "n"))]
  11197. !   "! (TARGET_486 || TARGET_PENTIUM) && GET_CODE (operands[2]) != CONST_INT"
  11198.     "*
  11199.   {
  11200.     CC_STATUS_INIT;
  11201. ***************
  11202. *** 4195,4201 ****
  11203.       (xor:SI (ashift:SI (const_int 1)
  11204.                  (match_operand:SI 1 "general_operand" "r"))
  11205.           (match_operand:SI 2 "general_operand" "0")))]
  11206. !   "TARGET_386 && GET_CODE (operands[1]) != CONST_INT"
  11207.     "*
  11208.   {
  11209.     CC_STATUS_INIT;
  11210. --- 3899,3905 ----
  11211.       (xor:SI (ashift:SI (const_int 1)
  11212.                  (match_operand:SI 1 "general_operand" "r"))
  11213.           (match_operand:SI 2 "general_operand" "0")))]
  11214. !   "! (TARGET_486 || TARGET_PENTIUM) && GET_CODE (operands[1]) != CONST_INT"
  11215.     "*
  11216.   {
  11217.     CC_STATUS_INIT;
  11218. ***************
  11219. *** 4208,4214 ****
  11220.       (xor:SI (match_operand:SI 1 "general_operand" "0")
  11221.           (ashift:SI (const_int 1)
  11222.                  (match_operand:SI 2 "general_operand" "r"))))]
  11223. !   "TARGET_386 && GET_CODE (operands[2]) != CONST_INT"
  11224.     "*
  11225.   {
  11226.     CC_STATUS_INIT;
  11227. --- 3912,3918 ----
  11228.       (xor:SI (match_operand:SI 1 "general_operand" "0")
  11229.           (ashift:SI (const_int 1)
  11230.                  (match_operand:SI 2 "general_operand" "r"))))]
  11231. !   "! (TARGET_486 || TARGET_PENTIUM) && GET_CODE (operands[2]) != CONST_INT"
  11232.     "*
  11233.   {
  11234.     CC_STATUS_INIT;
  11235. ***************
  11236. *** 4553,4558 ****
  11237. --- 4257,4271 ----
  11238.     if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  11239.       return \"jnc %l0\";
  11240.     else
  11241. +   /* intel1 */
  11242. +   if (cc_prev_status.flags & CC_TEST_AX)
  11243. +     {
  11244. +       operands[1] = gen_rtx (REG, SImode, 0);
  11245. +       operands[2] = GEN_INT (0x4000);
  11246. +       output_asm_insn (AS2 (testl,%2,%1), operands);
  11247. +       return AS1 (jne,%l0);
  11248. +     }
  11249.       return \"je %l0\";
  11250.   }")
  11251.   
  11252. ***************
  11253. *** 4585,4590 ****
  11254. --- 4298,4312 ----
  11255.     if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  11256.       return \"jc %l0\";
  11257.     else
  11258. +   /* intel1 */
  11259. +   if (cc_prev_status.flags & CC_TEST_AX)
  11260. +     {
  11261. +       operands[1] = gen_rtx (REG, SImode, 0);
  11262. +       operands[2] = GEN_INT (0x4000);
  11263. +       output_asm_insn (AS2 (testl,%2,%1), operands);
  11264. +       return AS1 (je,%l0);
  11265. +     }
  11266.       return \"jne %l0\";
  11267.   }")
  11268.   
  11269. ***************
  11270. *** 4610,4615 ****
  11271. --- 4332,4344 ----
  11272.     if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  11273.       return AS1 (je,%l0);
  11274.   
  11275. +   if (cc_prev_status.flags & CC_TEST_AX)
  11276. +     {
  11277. +       operands[1] = gen_rtx (REG, SImode, 0);
  11278. +       operands[2] = GEN_INT (0x4100);
  11279. +       output_asm_insn (AS2 (testl,%2,%1), operands);
  11280. +       return AS1 (je,%l0);
  11281. +     }
  11282.     OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
  11283.   }")
  11284.   
  11285. ***************
  11286. *** 4654,4659 ****
  11287. --- 4383,4396 ----
  11288.     if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  11289.       return AS1 (je,%l0);
  11290.   
  11291. +   /* intel1 */
  11292. +   if (cc_prev_status.flags & CC_TEST_AX)
  11293. +     {
  11294. +       operands[1] = gen_rtx (REG, SImode, 0);
  11295. +       operands[2] = GEN_INT (0x100);
  11296. +       output_asm_insn (AS2 (testl,%2,%1), operands);
  11297. +       return AS1 (jne,%l0);
  11298. +     }
  11299.     OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
  11300.   }")
  11301.   
  11302. ***************
  11303. *** 4697,4703 ****
  11304.   {
  11305.     if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  11306.       return AS1 (je,%l0);
  11307.     OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
  11308.   }")
  11309.   
  11310. --- 4434,4447 ----
  11311.   {
  11312.     if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  11313.       return AS1 (je,%l0);
  11314. !   /* intel1 */
  11315. !   if (cc_prev_status.flags & CC_TEST_AX)
  11316. !     {
  11317. !       operands[1] = gen_rtx (REG, SImode, 0);
  11318. !       operands[2] = GEN_INT (0x100);
  11319. !       output_asm_insn (AS2 (testl,%2,%1), operands);
  11320. !       return AS1 (je,%l0);
  11321. !     }
  11322.     OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
  11323.   }")
  11324.   
  11325. ***************
  11326. *** 4741,4746 ****
  11327. --- 4485,4498 ----
  11328.   {
  11329.     if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  11330.       return AS1 (jb,%l0);
  11331. +   /* intel1 */
  11332. +   if (cc_prev_status.flags & CC_TEST_AX)
  11333. +     {
  11334. +       operands[1] = gen_rtx (REG, SImode, 0);
  11335. +       operands[2] = GEN_INT (0x4100);
  11336. +       output_asm_insn (AS2 (testl,%2,%1), operands);
  11337. +       return AS1 (jne,%l0);
  11338. +     }
  11339.   
  11340.     OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
  11341.   }")
  11342. ***************
  11343. *** 4778,4783 ****
  11344. --- 4530,4543 ----
  11345.     if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  11346.       return \"jc %l0\";
  11347.     else
  11348. +   /* intel1 */
  11349. +   if (cc_prev_status.flags & CC_TEST_AX)
  11350. +     {
  11351. +       operands[1] = gen_rtx (REG, SImode, 0);
  11352. +       operands[2] = GEN_INT (0x4000);
  11353. +       output_asm_insn (AS2 (testl,%2,%1), operands);
  11354. +       return AS1 (je,%l0);
  11355. +     }
  11356.       return \"jne %l0\";
  11357.   }")
  11358.   
  11359. ***************
  11360. *** 4793,4798 ****
  11361. --- 4553,4566 ----
  11362.     if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  11363.       return \"jnc %l0\";
  11364.     else
  11365. +   /* intel1 */
  11366. +   if (cc_prev_status.flags & CC_TEST_AX)
  11367. +     {
  11368. +       operands[1] = gen_rtx (REG, SImode, 0);
  11369. +       operands[2] = GEN_INT (0x4000);
  11370. +       output_asm_insn (AS2 (testl,%2,%1), operands);
  11371. +       return AS1 (jne,%l0);
  11372. +     }
  11373.       return \"je %l0\";
  11374.   }")
  11375.   
  11376. ***************
  11377. *** 4807,4813 ****
  11378.   {
  11379.     if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  11380.       return AS1 (jne,%l0);
  11381.     OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
  11382.   }")
  11383.   
  11384. --- 4575,4588 ----
  11385.   {
  11386.     if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  11387.       return AS1 (jne,%l0);
  11388. !   /* intel1 */
  11389. !   if (cc_prev_status.flags & CC_TEST_AX)
  11390. !     {
  11391. !       operands[1] = gen_rtx (REG, SImode, 0);
  11392. !       operands[2] = GEN_INT (0x4100);
  11393. !       output_asm_insn (AS2 (testl,%2,%1), operands);
  11394. !       return AS1 (jne,%l0);
  11395. !     }
  11396.     OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
  11397.   }")
  11398.   
  11399. ***************
  11400. *** 4831,4836 ****
  11401. --- 4606,4619 ----
  11402.   {
  11403.     if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  11404.       return AS1 (jne,%l0);
  11405. +   /* intel1 */
  11406. +   if (cc_prev_status.flags & CC_TEST_AX)
  11407. +     {
  11408. +       operands[1] = gen_rtx (REG, SImode, 0);
  11409. +       operands[2] = GEN_INT (0x100);
  11410. +       output_asm_insn (AS2 (testl,%2,%1), operands);
  11411. +       return AS1 (je,%l0);
  11412. +     }
  11413.   
  11414.     OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
  11415.   }")
  11416. ***************
  11417. *** 4855,4861 ****
  11418.   {
  11419.     if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  11420.       return AS1 (jne,%l0);
  11421.     OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
  11422.   }")
  11423.   
  11424. --- 4638,4651 ----
  11425.   {
  11426.     if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  11427.       return AS1 (jne,%l0);
  11428. !   /* intel1 */
  11429. !   if (cc_prev_status.flags & CC_TEST_AX)
  11430. !     {
  11431. !       operands[1] = gen_rtx (REG, SImode, 0);
  11432. !       operands[2] = GEN_INT (0x100);
  11433. !       output_asm_insn (AS2 (testl,%2,%1), operands);
  11434. !       return AS1 (jne,%l0);
  11435. !     }
  11436.     OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
  11437.   }")
  11438.   
  11439. ***************
  11440. *** 4880,4885 ****
  11441. --- 4670,4683 ----
  11442.     if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  11443.       return AS1 (jae,%l0);
  11444.   
  11445. +   /* intel1 */
  11446. +   if (cc_prev_status.flags & CC_TEST_AX)
  11447. +     {
  11448. +       operands[1] = gen_rtx (REG, SImode, 0);
  11449. +       operands[2] = GEN_INT (0x4100);
  11450. +       output_asm_insn (AS2 (testl,%2,%1), operands);
  11451. +       return AS1 (je,%l0);
  11452. +     }
  11453.     OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
  11454.   }")
  11455.   
  11456. ***************
  11457. *** 5296,5346 ****
  11458.     "!HALF_PIC_P ()"
  11459.     "call %P1")
  11460.   
  11461. - ;; Call subroutine returning any type.
  11462.   (define_expand "untyped_call"
  11463. !   [(parallel [(call (match_operand 0 "" "")
  11464.               (const_int 0))
  11465. !           (match_operand 1 "" "")
  11466.             (match_operand 2 "" "")])]
  11467.     ""
  11468.     "
  11469.   {
  11470. !   int i;
  11471.   
  11472. !   /* In order to give reg-stack an easier job in validating two
  11473. !      coprocessor registers as containing a possible return value,
  11474. !      simply pretend the untyped call returns a complex long double
  11475. !      value.  */
  11476. !   emit_call_insn (TARGET_80387
  11477. !                   ? gen_call_value (gen_rtx (REG, XCmode, FIRST_FLOAT_REG),
  11478. !                           operands[0], const0_rtx)
  11479. !                   : gen_call (operands[0], const0_rtx));
  11480. !   for (i = 0; i < XVECLEN (operands[2], 0); i++)
  11481. !     {
  11482. !       rtx set = XVECEXP (operands[2], 0, i);
  11483. !       emit_move_insn (SET_DEST (set), SET_SRC (set));
  11484. !     }
  11485. !   /* The optimizer does not know that the call sets the function value
  11486. !      registers we stored in the result block.  We avoid problems by
  11487. !      claiming that all hard registers are used and clobbered at this
  11488. !      point.  */
  11489. !   emit_insn (gen_blockage ());
  11490.   
  11491. !   DONE;
  11492. ! }")
  11493.   
  11494. ! ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
  11495. ! ;; all of memory.  This blocks insns from being moved across this point.
  11496.   
  11497. ! (define_insn "blockage"
  11498. !   [(unspec_volatile [(const_int 0)] 0)]
  11499.     ""
  11500. !   "")
  11501.   
  11502. ! ;; Insn emitted into the body of a function to return from a function.
  11503.   ;; This is only done if the function's epilogue is known to be simple.
  11504.   ;; See comments for simple_386_epilogue in i386.c.
  11505.   
  11506. --- 5094,5221 ----
  11507.     "!HALF_PIC_P ()"
  11508.     "call %P1")
  11509.   
  11510.   (define_expand "untyped_call"
  11511. !   [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
  11512.               (const_int 0))
  11513. !           (match_operand:BLK 1 "memory_operand" "")
  11514.             (match_operand 2 "" "")])]
  11515.     ""
  11516.     "
  11517.   {
  11518. !   rtx addr;
  11519.   
  11520. !   if (flag_pic)
  11521. !     current_function_uses_pic_offset_table = 1;
  11522.   
  11523. !   /* With half-pic, force the address into a register.  */
  11524. !   addr = XEXP (operands[0], 0);
  11525. !   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  11526. !     XEXP (operands[0], 0) = force_reg (Pmode, addr);
  11527.   
  11528. !   operands[1] = change_address (operands[1], DImode, XEXP (operands[1], 0));
  11529. !   if (! expander_call_insn_operand (operands[1], QImode))
  11530. !     operands[1]
  11531. !       = change_address (operands[1], VOIDmode,
  11532. !             copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
  11533. ! }")
  11534.   
  11535. ! (define_insn ""
  11536. !   [(call (match_operand:QI 0 "call_insn_operand" "m")
  11537. !      (const_int 0))
  11538. !    (match_operand:DI 1 "memory_operand" "o")
  11539. !    (match_operand 2 "" "")]
  11540.     ""
  11541. !   "*
  11542. ! {
  11543. !   rtx addr = operands[1];
  11544.   
  11545. !   if (GET_CODE (operands[0]) == MEM
  11546. !       && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  11547. !     {
  11548. !       operands[0] = XEXP (operands[0], 0);
  11549. !       output_asm_insn (AS1 (call,%*%0), operands);
  11550. !     }
  11551. !   else
  11552. !     output_asm_insn (AS1 (call,%P0), operands);
  11553. !   operands[2] = gen_rtx (REG, SImode, 0);
  11554. !   output_asm_insn (AS2 (mov%L2,%2,%1), operands);
  11555. !   operands[2] = gen_rtx (REG, SImode, 1);
  11556. !   operands[1] = adj_offsettable_operand (addr, 4);
  11557. !   output_asm_insn (AS2 (mov%L2,%2,%1), operands);
  11558. !   operands[1] = adj_offsettable_operand (addr, 8);
  11559. !   return AS1 (fnsave,%1);
  11560. ! }")
  11561. ! (define_insn ""
  11562. !   [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
  11563. !      (const_int 0))
  11564. !    (match_operand:DI 1 "memory_operand" "o")
  11565. !    (match_operand 2 "" "")]
  11566. !   "!HALF_PIC_P ()"
  11567. !   "*
  11568. ! {
  11569. !   rtx addr = operands[1];
  11570. !   output_asm_insn (AS1 (call,%P0), operands);
  11571. !   operands[2] = gen_rtx (REG, SImode, 0);
  11572. !   output_asm_insn (AS2 (mov%L2,%2,%1), operands);
  11573. !   operands[2] = gen_rtx (REG, SImode, 1);
  11574. !   operands[1] = adj_offsettable_operand (addr, 4);
  11575. !   output_asm_insn (AS2 (mov%L2,%2,%1), operands);
  11576. !   operands[1] = adj_offsettable_operand (addr, 8);
  11577. !   return AS1 (fnsave,%1);
  11578. ! }")
  11579. ! ;; We use fnsave and frstor to save and restore the floating point result.
  11580. ! ;; These are expensive instructions and require a large space to save the
  11581. ! ;; FPU state.  An more complicated alternative is to use fnstenv to store
  11582. ! ;; the FPU environment and test whether the stack top is valid.  Store the
  11583. ! ;; result of the test, and if it is valid, pop and save the value.  The
  11584. ! ;; untyped_return would check the test and optionally push the saved value.
  11585. ! (define_expand "untyped_return"
  11586. !   [(match_operand:BLK 0 "memory_operand" "")
  11587. !    (match_operand 1 "" "")]
  11588. !   ""
  11589. !   "
  11590. ! {
  11591. !   rtx valreg1 = gen_rtx (REG, SImode, 0);
  11592. !   rtx valreg2 = gen_rtx (REG, SImode, 1);
  11593. !   rtx result = operands[0];
  11594. !   /* Restore the FPU state.  */
  11595. !   emit_insn (gen_update_return (change_address (result, SImode,
  11596. !                         plus_constant (XEXP (result, 0),
  11597. !                                    8))));
  11598. !   /* Reload the function value registers.  */
  11599. !   emit_move_insn (valreg1, change_address (result, SImode, XEXP (result, 0)));
  11600. !   emit_move_insn (valreg2,
  11601. !           change_address (result, SImode,
  11602. !                   plus_constant (XEXP (result, 0), 4)));
  11603. !   /* Put USE insns before the return.  */
  11604. !   emit_insn (gen_rtx (USE, VOIDmode, valreg1));
  11605. !   emit_insn (gen_rtx (USE, VOIDmode, valreg2));
  11606. !   /* Construct the return.  */
  11607. !   expand_null_return ();
  11608. !   DONE;
  11609. ! }")
  11610. ! (define_insn "update_return"
  11611. !   [(unspec:SI [(match_operand:SI 0 "memory_operand" "m")] 0)]
  11612. !   ""
  11613. !   "frstor %0")
  11614. ! ;; Insn emitted into the body of a function to return from a function.
  11615.   ;; This is only done if the function's epilogue is known to be simple.
  11616.   ;; See comments for simple_386_epilogue in i386.c.
  11617.   
  11618. ***************
  11619. *** 5387,5393 ****
  11620.   ;; It might seem that operands 0 & 1 could use predicate register_operand.
  11621.   ;; But strength reduction might offset the MEM expression.  So we let
  11622.   ;; reload put the address into %edi & %esi.
  11623.   (define_insn ""
  11624.     [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
  11625.       (mem:BLK (match_operand:SI 1 "address_operand" "S")))
  11626. --- 5262,5268 ----
  11627.   ;; It might seem that operands 0 & 1 could use predicate register_operand.
  11628.   ;; But strength reduction might offset the MEM expression.  So we let
  11629.   ;; reload put the address into %edi & %esi.
  11630. ! ;; intel1 "e" used to be "S"
  11631.   (define_insn ""
  11632.     [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
  11633.       (mem:BLK (match_operand:SI 1 "address_operand" "S")))
  11634. ***************
  11635. *** 5463,5468 ****
  11636. --- 5338,5344 ----
  11637.   ;; possible to know that the length is non-zero, and to avoid the extra
  11638.   ;; code to handle zero-length compares.
  11639.   
  11640. + ;; intel1 "e" used to be "S"
  11641.   (define_insn ""
  11642.     [(set (match_operand:SI 0 "general_operand" "=&r")
  11643.       (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
  11644. ***************
  11645. *** 5499,5504 ****
  11646. --- 5375,5381 ----
  11647.     RET;
  11648.   }")
  11649.   
  11650. + ;; intel1 "e" used to be "S"
  11651.   (define_insn ""
  11652.     [(set (cc0)
  11653.       (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
  11654. ***************
  11655. *** 5553,5571 ****
  11656.     output_asm_insn (AS2 (bsf%L0,%1,%0), xops);
  11657.   #ifdef LOCAL_LABEL_PREFIX
  11658.     sprintf (buffer, \"jnz %sLFFSSI%d\",
  11659. !        LOCAL_LABEL_PREFIX, ffssi_label_number);
  11660.   #else
  11661.     sprintf (buffer, \"jnz %sLFFSSI%d\",
  11662. !        \"\", ffssi_label_number);
  11663.   #endif
  11664.     output_asm_insn (buffer, xops);
  11665.     output_asm_insn (AS2 (mov%L0,%2,%0), xops);
  11666.   #ifdef LOCAL_LABEL_PREFIX
  11667.     sprintf (buffer, \"%sLFFSSI%d:\",
  11668. !        LOCAL_LABEL_PREFIX, ffssi_label_number);
  11669.   #else
  11670.     sprintf (buffer, \"%sLFFSSI%d:\",
  11671. !        \"\", ffssi_label_number);
  11672.   #endif
  11673.     output_asm_insn (buffer, xops);
  11674.   
  11675. --- 5430,5448 ----
  11676.     output_asm_insn (AS2 (bsf%L0,%1,%0), xops);
  11677.   #ifdef LOCAL_LABEL_PREFIX
  11678.     sprintf (buffer, \"jnz %sLFFSSI%d\",
  11679. !          LOCAL_LABEL_PREFIX, ffssi_label_number);
  11680.   #else
  11681.     sprintf (buffer, \"jnz %sLFFSSI%d\",
  11682. !          \"\", ffssi_label_number);
  11683.   #endif
  11684.     output_asm_insn (buffer, xops);
  11685.     output_asm_insn (AS2 (mov%L0,%2,%0), xops);
  11686.   #ifdef LOCAL_LABEL_PREFIX
  11687.     sprintf (buffer, \"%sLFFSSI%d:\",
  11688. !          LOCAL_LABEL_PREFIX, ffssi_label_number);
  11689.   #else
  11690.     sprintf (buffer, \"%sLFFSSI%d:\",
  11691. !          \"\", ffssi_label_number);
  11692.   #endif
  11693.     output_asm_insn (buffer, xops);
  11694.   
  11695. ***************
  11696. *** 5599,5617 ****
  11697.     output_asm_insn (AS2 (bsf%W0,%1,%0), xops);
  11698.   #ifdef LOCAL_LABEL_PREFIX
  11699.     sprintf (buffer, \"jnz %sLFFSHI%d\",
  11700. !        LOCAL_LABEL_PREFIX, ffshi_label_number);
  11701.   #else
  11702.     sprintf (buffer, \"jnz %sLFFSHI%d\",
  11703. !        \"\", ffshi_label_number);
  11704.   #endif
  11705.     output_asm_insn (buffer, xops);
  11706.     output_asm_insn (AS2 (mov%W0,%2,%0), xops);
  11707.   #ifdef LOCAL_LABEL_PREFIX
  11708.     sprintf (buffer, \"%sLFFSHI%d:\",
  11709. !        LOCAL_LABEL_PREFIX, ffshi_label_number);
  11710.   #else
  11711.     sprintf (buffer, \"%sLFFSHI%d:\",
  11712. !        \"\", ffshi_label_number);
  11713.   #endif
  11714.     output_asm_insn (buffer, xops);
  11715.   
  11716. --- 5476,5494 ----
  11717.     output_asm_insn (AS2 (bsf%W0,%1,%0), xops);
  11718.   #ifdef LOCAL_LABEL_PREFIX
  11719.     sprintf (buffer, \"jnz %sLFFSHI%d\",
  11720. !          LOCAL_LABEL_PREFIX, ffshi_label_number);
  11721.   #else
  11722.     sprintf (buffer, \"jnz %sLFFSHI%d\",
  11723. !          \"\", ffshi_label_number);
  11724.   #endif
  11725.     output_asm_insn (buffer, xops);
  11726.     output_asm_insn (AS2 (mov%W0,%2,%0), xops);
  11727.   #ifdef LOCAL_LABEL_PREFIX
  11728.     sprintf (buffer, \"%sLFFSHI%d:\",
  11729. !          LOCAL_LABEL_PREFIX, ffshi_label_number);
  11730.   #else
  11731.     sprintf (buffer, \"%sLFFSHI%d:\",
  11732. !          \"\", ffshi_label_number);
  11733.   #endif
  11734.     output_asm_insn (buffer, xops);
  11735.   
  11736. ***************
  11737. *** 5626,5639 ****
  11738.   ;; the other operand a conversion.  The conversion may be SFmode or
  11739.   ;; SImode if the target mode DFmode, but only SImode if the target mode
  11740.   ;; is SFmode.
  11741.   (define_insn ""
  11742.     [(set (match_operand:DF 0 "register_operand" "=f,f")
  11743.       (match_operator:DF 3 "binary_387_op"
  11744.               [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
  11745. !              (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
  11746.     "TARGET_80387"
  11747. !   "* return output_387_binary_op (insn, operands);")
  11748.   
  11749.   (define_insn ""
  11750.     [(set (match_operand:DF 0 "register_operand" "=f")
  11751. --- 5503,5525 ----
  11752.   ;; the other operand a conversion.  The conversion may be SFmode or
  11753.   ;; SImode if the target mode DFmode, but only SImode if the target mode
  11754.   ;; is SFmode.
  11755. ! ;; intel1 2 changed from nonimmediate operand to general operand
  11756.   (define_insn ""
  11757.     [(set (match_operand:DF 0 "register_operand" "=f,f")
  11758.       (match_operator:DF 3 "binary_387_op"
  11759.               [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
  11760. !              (match_operand:DF 2 "general_operand" "fm,0")]))]
  11761.     "TARGET_80387"
  11762. !   "* return (char *) output_387_binary_op (insn, operands);"
  11763. !   [(set (attr "type") 
  11764. !         (cond [(match_operand:DF 3 "is_mul" "") 
  11765. !                  (const_string "fpop")
  11766. !                (match_operand:DF 3 "is_div" "") 
  11767. !                  (const_string "fpdiv")
  11768. !               ]
  11769. !                (const_string "fpop")
  11770. !         )
  11771. !   )])
  11772.   
  11773.   (define_insn ""
  11774.     [(set (match_operand:DF 0 "register_operand" "=f")
  11775. ***************
  11776. *** 5641,5647 ****
  11777.          [(float:DF (match_operand:SI 1 "general_operand" "rm"))
  11778.           (match_operand:DF 2 "general_operand" "0")]))]
  11779.     "TARGET_80387"
  11780. !   "* return output_387_binary_op (insn, operands);")
  11781.   
  11782.   (define_insn ""
  11783.     [(set (match_operand:XF 0 "register_operand" "=f,f")
  11784. --- 5527,5533 ----
  11785.          [(float:DF (match_operand:SI 1 "general_operand" "rm"))
  11786.           (match_operand:DF 2 "general_operand" "0")]))]
  11787.     "TARGET_80387"
  11788. !   "* return (char *) output_387_binary_op (insn, operands);")
  11789.   
  11790.   (define_insn ""
  11791.     [(set (match_operand:XF 0 "register_operand" "=f,f")
  11792. ***************
  11793. *** 5649,5655 ****
  11794.               [(match_operand:XF 1 "nonimmediate_operand" "0,f")
  11795.                (match_operand:XF 2 "nonimmediate_operand" "f,0")]))]
  11796.     "TARGET_80387"
  11797. !   "* return output_387_binary_op (insn, operands);")
  11798.   
  11799.   (define_insn ""
  11800.     [(set (match_operand:XF 0 "register_operand" "=f")
  11801. --- 5535,5541 ----
  11802.               [(match_operand:XF 1 "nonimmediate_operand" "0,f")
  11803.                (match_operand:XF 2 "nonimmediate_operand" "f,0")]))]
  11804.     "TARGET_80387"
  11805. !   "* return (char *) output_387_binary_op (insn, operands);")
  11806.   
  11807.   (define_insn ""
  11808.     [(set (match_operand:XF 0 "register_operand" "=f")
  11809. ***************
  11810. *** 5657,5663 ****
  11811.          [(float:XF (match_operand:SI 1 "general_operand" "rm"))
  11812.           (match_operand:XF 2 "general_operand" "0")]))]
  11813.     "TARGET_80387"
  11814. !   "* return output_387_binary_op (insn, operands);")
  11815.   
  11816.   (define_insn ""
  11817.     [(set (match_operand:XF 0 "register_operand" "=f,f")
  11818. --- 5543,5549 ----
  11819.          [(float:XF (match_operand:SI 1 "general_operand" "rm"))
  11820.           (match_operand:XF 2 "general_operand" "0")]))]
  11821.     "TARGET_80387"
  11822. !   "* return (char *) output_387_binary_op (insn, operands);")
  11823.   
  11824.   (define_insn ""
  11825.     [(set (match_operand:XF 0 "register_operand" "=f,f")
  11826. ***************
  11827. *** 5665,5671 ****
  11828.          [(float_extend:XF (match_operand:SF 1 "general_operand" "fm,0"))
  11829.           (match_operand:XF 2 "general_operand" "0,f")]))]
  11830.     "TARGET_80387"
  11831. !   "* return output_387_binary_op (insn, operands);")
  11832.   
  11833.   (define_insn ""
  11834.     [(set (match_operand:XF 0 "register_operand" "=f")
  11835. --- 5551,5557 ----
  11836.          [(float_extend:XF (match_operand:SF 1 "general_operand" "fm,0"))
  11837.           (match_operand:XF 2 "general_operand" "0,f")]))]
  11838.     "TARGET_80387"
  11839. !   "* return (char *) output_387_binary_op (insn, operands);")
  11840.   
  11841.   (define_insn ""
  11842.     [(set (match_operand:XF 0 "register_operand" "=f")
  11843. ***************
  11844. *** 5673,5679 ****
  11845.         [(match_operand:XF 1 "general_operand" "0")
  11846.          (float:XF (match_operand:SI 2 "general_operand" "rm"))]))]
  11847.     "TARGET_80387"
  11848. !   "* return output_387_binary_op (insn, operands);")
  11849.   
  11850.   (define_insn ""
  11851.     [(set (match_operand:XF 0 "register_operand" "=f,f")
  11852. --- 5559,5565 ----
  11853.         [(match_operand:XF 1 "general_operand" "0")
  11854.          (float:XF (match_operand:SI 2 "general_operand" "rm"))]))]
  11855.     "TARGET_80387"
  11856. !   "* return (char *) output_387_binary_op (insn, operands);")
  11857.   
  11858.   (define_insn ""
  11859.     [(set (match_operand:XF 0 "register_operand" "=f,f")
  11860. ***************
  11861. *** 5681,5688 ****
  11862.         [(match_operand:XF 1 "general_operand" "0,f")
  11863.          (float_extend:XF
  11864.           (match_operand:SF 2 "general_operand" "fm,0"))]))]
  11865.     "TARGET_80387"
  11866. !   "* return output_387_binary_op (insn, operands);")
  11867.   
  11868.   (define_insn ""
  11869.     [(set (match_operand:DF 0 "register_operand" "=f,f")
  11870. --- 5567,5584 ----
  11871.         [(match_operand:XF 1 "general_operand" "0,f")
  11872.          (float_extend:XF
  11873.           (match_operand:SF 2 "general_operand" "fm,0"))]))]
  11874.     "TARGET_80387"
  11875. !   "* return (char *) output_387_binary_op (insn, operands);"
  11876. !   [(set (attr "type") 
  11877. !         (cond [(match_operand:DF 3 "is_mul" "") 
  11878. !                  (const_string "fpop")
  11879. !                (match_operand:DF 3 "is_div" "") 
  11880. !                  (const_string "fpdiv")
  11881. !               ]
  11882. !                (const_string "fpop")
  11883. !         )
  11884. !   )])
  11885.   
  11886.   (define_insn ""
  11887.     [(set (match_operand:DF 0 "register_operand" "=f,f")
  11888. ***************
  11889. *** 5690,5696 ****
  11890.          [(float_extend:DF (match_operand:SF 1 "general_operand" "fm,0"))
  11891.           (match_operand:DF 2 "general_operand" "0,f")]))]
  11892.     "TARGET_80387"
  11893. !   "* return output_387_binary_op (insn, operands);")
  11894.   
  11895.   (define_insn ""
  11896.     [(set (match_operand:DF 0 "register_operand" "=f")
  11897. --- 5586,5601 ----
  11898.          [(float_extend:DF (match_operand:SF 1 "general_operand" "fm,0"))
  11899.           (match_operand:DF 2 "general_operand" "0,f")]))]
  11900.     "TARGET_80387"
  11901. !   "* return (char *) output_387_binary_op (insn, operands);"
  11902. !   [(set (attr "type") 
  11903. !         (cond [(match_operand:DF 3 "is_mul" "") 
  11904. !                  (const_string "fpop")
  11905. !                (match_operand:DF 3 "is_div" "") 
  11906. !                  (const_string "fpdiv")
  11907. !               ]
  11908. !                (const_string "fpop")
  11909. !         )
  11910. !   )])
  11911.   
  11912.   (define_insn ""
  11913.     [(set (match_operand:DF 0 "register_operand" "=f")
  11914. ***************
  11915. *** 5698,5704 ****
  11916.         [(match_operand:DF 1 "general_operand" "0")
  11917.          (float:DF (match_operand:SI 2 "general_operand" "rm"))]))]
  11918.     "TARGET_80387"
  11919. !   "* return output_387_binary_op (insn, operands);")
  11920.   
  11921.   (define_insn ""
  11922.     [(set (match_operand:DF 0 "register_operand" "=f,f")
  11923. --- 5603,5618 ----
  11924.         [(match_operand:DF 1 "general_operand" "0")
  11925.          (float:DF (match_operand:SI 2 "general_operand" "rm"))]))]
  11926.     "TARGET_80387"
  11927. !   "* return (char *) output_387_binary_op (insn, operands);"
  11928. !   [(set (attr "type") 
  11929. !         (cond [(match_operand:DF 3 "is_mul" "") 
  11930. !                  (const_string "fpop")
  11931. !                (match_operand:DF 3 "is_div" "") 
  11932. !                  (const_string "fpdiv")
  11933. !               ]
  11934. !                (const_string "fpop")
  11935. !         )
  11936. !   )])
  11937.   
  11938.   (define_insn ""
  11939.     [(set (match_operand:DF 0 "register_operand" "=f,f")
  11940. ***************
  11941. *** 5707,5721 ****
  11942.          (float_extend:DF
  11943.           (match_operand:SF 2 "general_operand" "fm,0"))]))]
  11944.     "TARGET_80387"
  11945. !   "* return output_387_binary_op (insn, operands);")
  11946.   
  11947.   (define_insn ""
  11948.     [(set (match_operand:SF 0 "register_operand" "=f,f")
  11949.       (match_operator:SF 3 "binary_387_op"
  11950. !             [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
  11951. !              (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
  11952.     "TARGET_80387"
  11953. !   "* return output_387_binary_op (insn, operands);")
  11954.   
  11955.   (define_insn ""
  11956.     [(set (match_operand:SF 0 "register_operand" "=f")
  11957. --- 5621,5654 ----
  11958.          (float_extend:DF
  11959.           (match_operand:SF 2 "general_operand" "fm,0"))]))]
  11960.     "TARGET_80387"
  11961. !   "* return (char *) output_387_binary_op (insn, operands);"
  11962. !   [(set (attr "type") 
  11963. !         (cond [(match_operand:DF 3 "is_mul" "") 
  11964. !                  (const_string "fpop")
  11965. !                (match_operand:DF 3 "is_div" "") 
  11966. !                  (const_string "fpdiv")
  11967. !               ]
  11968. !                (const_string "fpop")
  11969. !         )
  11970. !   )])
  11971.   
  11972. + ;; intel1 1 and 2 changed from nonimmediate operand to general operand
  11973.   (define_insn ""
  11974.     [(set (match_operand:SF 0 "register_operand" "=f,f")
  11975.       (match_operator:SF 3 "binary_387_op"
  11976. !             [(match_operand:SF 1 "general_operand" "0,fm")
  11977. !              (match_operand:SF 2 "general_operand" "fm,0")]))]
  11978.     "TARGET_80387"
  11979. !   "* return (char *) output_387_binary_op (insn, operands);"
  11980. !   [(set (attr "type") 
  11981. !         (cond [(match_operand:DF 3 "is_mul" "") 
  11982. !                  (const_string "fpop")
  11983. !                (match_operand:DF 3 "is_div" "") 
  11984. !                  (const_string "fpdiv")
  11985. !               ]
  11986. !                (const_string "fpop")
  11987. !         )
  11988. !   )])
  11989.   
  11990.   (define_insn ""
  11991.     [(set (match_operand:SF 0 "register_operand" "=f")
  11992. ***************
  11993. *** 5723,5729 ****
  11994.         [(float:SF (match_operand:SI 1 "general_operand" "rm"))
  11995.          (match_operand:SF 2 "general_operand" "0")]))]
  11996.     "TARGET_80387"
  11997. !   "* return output_387_binary_op (insn, operands);")
  11998.   
  11999.   (define_insn ""
  12000.     [(set (match_operand:SF 0 "register_operand" "=f")
  12001. --- 5656,5671 ----
  12002.         [(float:SF (match_operand:SI 1 "general_operand" "rm"))
  12003.          (match_operand:SF 2 "general_operand" "0")]))]
  12004.     "TARGET_80387"
  12005. !   "* return (char *) output_387_binary_op (insn, operands);"
  12006. !   [(set (attr "type") 
  12007. !         (cond [(match_operand:DF 3 "is_mul" "") 
  12008. !                  (const_string "fpop")
  12009. !                (match_operand:DF 3 "is_div" "") 
  12010. !                  (const_string "fpdiv")
  12011. !               ]
  12012. !                (const_string "fpop")
  12013. !         )
  12014. !   )])
  12015.   
  12016.   (define_insn ""
  12017.     [(set (match_operand:SF 0 "register_operand" "=f")
  12018. ***************
  12019. *** 5731,5737 ****
  12020.         [(match_operand:SF 1 "general_operand" "0")
  12021.          (float:SF (match_operand:SI 2 "general_operand" "rm"))]))]
  12022.     "TARGET_80387"
  12023. !   "* return output_387_binary_op (insn, operands);")
  12024.   
  12025.   (define_expand "strlensi"
  12026.     [(parallel [(set (match_dup 4)
  12027. --- 5673,5688 ----
  12028.         [(match_operand:SF 1 "general_operand" "0")
  12029.          (float:SF (match_operand:SI 2 "general_operand" "rm"))]))]
  12030.     "TARGET_80387"
  12031. !   "* return (char *) output_387_binary_op (insn, operands);"
  12032. !   [(set (attr "type") 
  12033. !         (cond [(match_operand:DF 3 "is_mul" "") 
  12034. !                  (const_string "fpop")
  12035. !                (match_operand:DF 3 "is_div" "") 
  12036. !                  (const_string "fpdiv")
  12037. !               ]
  12038. !                (const_string "fpop")
  12039. !         )
  12040. !   )])
  12041.   
  12042.   (define_expand "strlensi"
  12043.     [(parallel [(set (match_dup 4)
  12044. ***************
  12045. *** 5773,5775 ****
  12046. --- 5724,6535 ----
  12047.     output_asm_insn (AS2 (mov%L0,%1,%0), xops);
  12048.     return \"repnz\;scas%B2\";
  12049.   }")
  12050. + ;; intel1 peepholes
  12051. + ;; change fstp mem1
  12052. + ;;        fld  mem1
  12053. + ;;        fop  mem2
  12054. + ;; to
  12055. + ;;        fst  mem1
  12056. + ;;        fop  mem2
  12057. + (define_peephole
  12058. +  [(set (match_operand:DF 0 "memory_operand" "g")
  12059. +        (reg:DF 8))
  12060. +   (set (reg:DF 8)
  12061. +        (match_operand:DF 1 "memory_operand" "g"))
  12062. +   (set (reg:DF 8)
  12063. +     (mult:DF (reg:DF 8)
  12064. +          (match_dup 0)))
  12065. +  ]
  12066. +  "TARGET_80387"
  12067. +  "*
  12068. +  {
  12069. +   extern int flag_float_store;
  12070. +   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  12071. +     {
  12072. +       if (flag_float_store)
  12073. +         {
  12074. +           output_asm_insn (AS1 (fstpl,%0),operands);
  12075. +           output_asm_insn (AS1 (fldl,%1),operands);
  12076. +           return AS1(fmull,%0);
  12077. +         }
  12078. +       output_asm_insn (AS1 (fstl,%0),operands);
  12079. +       return AS1(fmull,%1);
  12080. +     }
  12081. +   else
  12082. +     {
  12083. +       output_asm_insn (AS1 (fstl,%0),operands);
  12084. +       output_asm_insn (AS1 (fldl,%1),operands);
  12085. +       return AS1(fmull,%0);
  12086. +     }
  12087. +  }"
  12088. + );
  12089. +  
  12090. +  
  12091. +  
  12092. + (define_peephole
  12093. +  [(set (match_operand:DF 0 "memory_operand" "g")
  12094. +        (reg:DF 8))
  12095. +   (set (reg:DF 8)
  12096. +        (match_operand:DF 1 "memory_operand" "g"))
  12097. +   (set (reg:DF 8)
  12098. +     (plus:DF (reg:DF 8)
  12099. +          (match_dup 0)))
  12100. +  ]
  12101. +  "TARGET_80387"
  12102. +  "*
  12103. +  {
  12104. +   extern int flag_float_store;
  12105. +   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  12106. +     {
  12107. +       if (flag_float_store)
  12108. +         {
  12109. +           output_asm_insn (AS1 (fstpl,%0),operands);
  12110. +           output_asm_insn (AS1 (fldl,%1),operands);
  12111. +           return AS1(faddl,%0);
  12112. +         }
  12113. +       output_asm_insn (AS1 (fstl,%0),operands);
  12114. +       return AS1(faddl,%1);
  12115. +     }
  12116. +   else
  12117. +     {
  12118. +       output_asm_insn (AS1 (fstl,%0),operands);
  12119. +       output_asm_insn (AS1 (fldl,%1),operands);
  12120. +       return AS1(faddl,%0);
  12121. +     }
  12122. +  }"
  12123. + );
  12124. +  
  12125. +  
  12126. +  
  12127. + (define_peephole
  12128. +  [(set (match_operand:DF 0 "memory_operand" "g")
  12129. +        (reg:DF 8))
  12130. +   (set (reg:DF 8)
  12131. +        (match_operand:DF 1 "memory_operand" "g"))
  12132. +   (set (reg:DF 8)
  12133. +     (minus:DF (reg:DF 8)
  12134. +          (match_dup 0)))
  12135. +  ]
  12136. +  "TARGET_80387"
  12137. +  "*
  12138. +  {
  12139. +   extern int flag_float_store;
  12140. +   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  12141. +     {
  12142. +       if (flag_float_store)
  12143. +         {
  12144. +           output_asm_insn (AS1 (fstpl,%0),operands);
  12145. +           output_asm_insn (AS1 (fldl,%1),operands);
  12146. +           return AS1(fsubl,%0);
  12147. +         }
  12148. +       output_asm_insn (AS1 (fstl,%0),operands);
  12149. +       return AS1(fsubrl,%1);
  12150. +     }
  12151. +   else
  12152. +     {
  12153. +       output_asm_insn (AS1 (fstl,%0),operands);
  12154. +       output_asm_insn (AS1 (fldl,%1),operands);
  12155. +       return AS1(fsubl,%0);
  12156. +     }
  12157. +  }"
  12158. + );
  12159. +  
  12160. +  
  12161. +  
  12162. + (define_peephole
  12163. +  [(set (match_operand:DF 0 "memory_operand" "g")
  12164. +        (reg:DF 8))
  12165. +   (set (reg:DF 8)
  12166. +        (match_operand:DF 1 "memory_operand" "g"))
  12167. +   (set (reg:DF 8)
  12168. +     (div:DF (reg:DF 8)
  12169. +          (match_dup 0)))
  12170. +  ]
  12171. +  "TARGET_80387"
  12172. +  "*
  12173. +  {
  12174. +   extern int flag_float_store;
  12175. +   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  12176. +     {
  12177. +       if (flag_float_store)
  12178. +         {
  12179. +           output_asm_insn (AS1 (fstpl,%0),operands);
  12180. +           output_asm_insn (AS1 (fldl,%1),operands);
  12181. +           return AS1(fdivl,%0);
  12182. +         }
  12183. +       output_asm_insn (AS1 (fstl,%0),operands);
  12184. +       return AS1(fdivrl,%1);
  12185. +     }
  12186. +   else
  12187. +     {
  12188. +       output_asm_insn (AS1 (fstl,%0),operands);
  12189. +       output_asm_insn (AS1 (fldl,%1),operands);
  12190. +       return AS1(fdivl,%0);
  12191. +     }
  12192. +  }"
  12193. + );
  12194. +  
  12195. +  
  12196. + (define_peephole
  12197. +  [(set (match_operand:SF 0 "memory_operand" "g")
  12198. +        (reg:SF 8))
  12199. +   (set (reg:SF 8)
  12200. +        (match_operand:SF 1 "memory_operand" "g"))
  12201. +   (set (reg:SF 8)
  12202. +     (mult:SF (reg:SF 8)
  12203. +          (match_dup 0)))
  12204. +  ]
  12205. +  "TARGET_80387"
  12206. +  "*
  12207. +  {
  12208. +   extern int flag_float_store;
  12209. +   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  12210. +     {
  12211. +       if (flag_float_store)
  12212. +         {
  12213. +           output_asm_insn (AS1 (fstps,%0),operands);
  12214. +           output_asm_insn (AS1 (flds,%1),operands);
  12215. +           return AS1(fmuls,%0);
  12216. +         }
  12217. +       output_asm_insn (AS1 (fsts,%0),operands);
  12218. +       return AS1(fmuls,%1);
  12219. +     }
  12220. +   else
  12221. +     {
  12222. +       output_asm_insn (AS1 (fsts,%0),operands);
  12223. +       output_asm_insn (AS1 (flds,%1),operands);
  12224. +       return AS1(fmuls,%0);
  12225. +     }
  12226. +  }"
  12227. + );
  12228. +  
  12229. +  
  12230. +  
  12231. + (define_peephole
  12232. +  [(set (match_operand:SF 0 "memory_operand" "g")
  12233. +        (reg:SF 8))
  12234. +   (set (reg:SF 8)
  12235. +        (match_operand:SF 1 "memory_operand" "g"))
  12236. +   (set (reg:SF 8)
  12237. +     (plus:SF (reg:SF 8)
  12238. +          (match_dup 0)))
  12239. +  ]
  12240. +  "TARGET_80387"
  12241. +  "*
  12242. +  {
  12243. +   extern int flag_float_store;
  12244. +   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  12245. +     {
  12246. +       if (flag_float_store)
  12247. +         {
  12248. +           output_asm_insn (AS1 (fstps,%0),operands);
  12249. +           output_asm_insn (AS1 (flds,%1),operands);
  12250. +           return AS1(fadds,%0);
  12251. +         }
  12252. +       output_asm_insn (AS1 (fsts,%0),operands);
  12253. +       return AS1(fadds,%1);
  12254. +     }
  12255. +   else
  12256. +     {
  12257. +       output_asm_insn (AS1 (fsts,%0),operands);
  12258. +       output_asm_insn (AS1 (flds,%1),operands);
  12259. +       return AS1(fadds,%0);
  12260. +     }
  12261. +  }"
  12262. + );
  12263. +  
  12264. +  
  12265. +  
  12266. + (define_peephole
  12267. +  [(set (match_operand:SF 0 "memory_operand" "g")
  12268. +        (reg:SF 8))
  12269. +   (set (reg:SF 8)
  12270. +        (match_operand:SF 1 "memory_operand" "g"))
  12271. +   (set (reg:SF 8)
  12272. +     (minus:SF (reg:SF 8)
  12273. +          (match_dup 0)))
  12274. +  ]
  12275. +  "TARGET_80387"
  12276. +  "*
  12277. +  {
  12278. +   extern int flag_float_store;
  12279. +   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  12280. +     {
  12281. +       if (flag_float_store)
  12282. +         {
  12283. +           output_asm_insn (AS1 (fstps,%0),operands);
  12284. +           output_asm_insn (AS1 (flds,%1),operands);
  12285. +           return AS1(fsubs,%0);
  12286. +         }
  12287. +       output_asm_insn (AS1 (fsts,%0),operands);
  12288. +       return AS1(fsubrs,%1);
  12289. +     }
  12290. +   else
  12291. +     {
  12292. +       output_asm_insn (AS1 (fsts,%0),operands);
  12293. +       output_asm_insn (AS1 (flds,%1),operands);
  12294. +       return AS1(fsubs,%0);
  12295. +     }
  12296. +  }"
  12297. + );
  12298. +  
  12299. +  
  12300. +  
  12301. + (define_peephole
  12302. +  [(set (match_operand:SF 0 "memory_operand" "g")
  12303. +        (reg:SF 8))
  12304. +   (set (reg:SF 8)
  12305. +        (match_operand:SF 1 "memory_operand" "g"))
  12306. +   (set (reg:SF 8)
  12307. +     (div:SF (reg:SF 8)
  12308. +          (match_dup 0)))
  12309. +  ]
  12310. +  "TARGET_80387"
  12311. +  "*
  12312. +  {
  12313. +   extern int flag_float_store;
  12314. +   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  12315. +     {
  12316. +       if (flag_float_store)
  12317. +         {
  12318. +           output_asm_insn (AS1 (fstps,%0),operands);
  12319. +           output_asm_insn (AS1 (flds,%1),operands);
  12320. +           return AS1(fdivs,%0);
  12321. +         }
  12322. +       output_asm_insn (AS1 (fsts,%0),operands);
  12323. +       return AS1(fdivrs,%1);
  12324. +     }
  12325. +   else
  12326. +     {
  12327. +       output_asm_insn (AS1 (fsts,%0),operands);
  12328. +       output_asm_insn (AS1 (flds,%1),operands);
  12329. +       return AS1(fdivs,%0);
  12330. +     }
  12331. +  }"
  12332. + );
  12333. +  
  12334. +  
  12335. + ;; change fstp mem1
  12336. + ;;        fld  mem1
  12337. + ;; to
  12338. + ;;        fst  mem1
  12339. +  
  12340. + (define_peephole
  12341. +  [(set (match_operand:DF 0 "memory_operand" "g")
  12342. +        (reg:DF 8))
  12343. +   (set (reg:DF 8)
  12344. +        (match_dup 0))]
  12345. +  "TARGET_80387"
  12346. +  "*
  12347. +  {
  12348. +   extern int flag_float_store;
  12349. +   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  12350. +     {
  12351. +       if(!MEM_VOLATILE_P (operands[0]) && !flag_float_store)
  12352. +         {
  12353. +           return AS1 (fstl,%0);
  12354. +         }
  12355. +       else
  12356. +         {
  12357. +          output_asm_insn (AS1 (fstpl,%0),operands);
  12358. +          return AS1 (fldl,%0);
  12359. +         }
  12360. +     }
  12361. +   else
  12362. +     {
  12363. +       output_asm_insn (AS1 (fstl,%0),operands);
  12364. +       return AS1 (fldl,%0);
  12365. +     }
  12366. +  }"
  12367. + );
  12368. + (define_peephole
  12369. +  [(set (match_operand:SF 0 "memory_operand" "g")
  12370. +        (reg:SF 8))
  12371. +   (set (reg:SF 8)
  12372. +        (match_dup 0))]
  12373. +  "TARGET_80387"
  12374. +  "*
  12375. +  {
  12376. +   extern int flag_float_store;
  12377. +   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  12378. +     {
  12379. +       if(!MEM_VOLATILE_P (operands[0]) && !flag_float_store)
  12380. +         {
  12381. +           return AS1 (fsts,%0);
  12382. +         }
  12383. +       else
  12384. +         {
  12385. +          output_asm_insn (AS1 (fstps,%0),operands);
  12386. +          return AS1 (flds,%0);
  12387. +         }
  12388. +     }
  12389. +   else
  12390. +     {
  12391. +       output_asm_insn (AS1 (fsts,%0),operands);
  12392. +       return AS1 (flds,%0);
  12393. +     }
  12394. +  }"
  12395. + );
  12396. + (define_peephole
  12397. +  [(set (match_operand:SF 0 "memory_operand" "g")
  12398. +        (reg:SF 8))
  12399. +   (set (reg:DF 8)
  12400. +        (float_extend:DF (match_dup 0)))]
  12401. +  "TARGET_80387"
  12402. +  "*
  12403. +  {
  12404. +   extern int flag_float_store;
  12405. +   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) && !flag_float_store)
  12406. +     {
  12407. +       return AS1 (fsts,%0);
  12408. +     }
  12409. +   else
  12410. +     {
  12411. +       output_asm_insn (AS1 (fsts,%0),operands);
  12412. +       return AS1 (flds,%0);
  12413. +     }
  12414. +  }"
  12415. + );
  12416. + ;; see if compare can be deleted
  12417. + (define_peephole
  12418. +   [
  12419. +    (set (cc0)
  12420. +     (compare (const_int 0)
  12421. +          (match_operand:SI 0 "general_operand" "g")))
  12422. +    (set (pc)
  12423. +     (if_then_else (ne (cc0)
  12424. +               (const_int 0))
  12425. +               (label_ref (match_operand 1 "" ""))
  12426. +               (pc)))
  12427. +   ]
  12428. +   ""
  12429. +   "*
  12430. + {
  12431. +       if(!last_to_set_cc(operands[0]),insn)
  12432. +       {
  12433. +         operands[2] = const0_rtx;
  12434. +         output_asm_insn (AS2 (cmp%L0,%2,%0),operands);
  12435. +         return \"jne %l1\";
  12436. +       }
  12437. +       else
  12438. +       {
  12439. +         return \"jne %l1\";
  12440. +       }
  12441. + }");
  12442. +   
  12443. + (define_peephole
  12444. +   [
  12445. +    (set (cc0)
  12446. +     (compare (match_operand:SI 0 "general_operand" "g")
  12447. +          (const_int 0)))
  12448. +    (set (pc)
  12449. +     (if_then_else (ne (cc0)
  12450. +               (const_int 0))
  12451. +               (label_ref (match_operand 1 "" ""))
  12452. +               (pc)))
  12453. +   ]
  12454. +   ""
  12455. +   "*
  12456. + {
  12457. +       if(!last_to_set_cc(operands[0],insn))
  12458. +       {
  12459. +         operands[2] = const0_rtx;
  12460. +         output_asm_insn (AS2 (cmp%L0,%2,%0),operands);
  12461. +         return \"jne %l1\";
  12462. +       }
  12463. +       else
  12464. +       {
  12465. +         return \"jne %l1\";
  12466. +       }
  12467. + }");
  12468. + ;; optimization of sign_extend combined with and
  12469. + (define_peephole
  12470. +   [
  12471. +    (set (match_operand:HI 0 "register_operand" "")
  12472. +     (and:HI (match_dup 0)
  12473. +         (match_operand:HI 1 "immediate_operand" "")))
  12474. +    (set (match_operand:SI 2 "register_operand" "")
  12475. +     (sign_extend:SI
  12476. +      (match_dup 0)))
  12477. +   ]
  12478. +   ""
  12479. +   "*
  12480. + {
  12481. +       int no_sign_extend = 0;
  12482. +       rtx note;
  12483. +       if ((INTVAL (operands[1]) & 0x8000) == 0)
  12484. +         { /* Don't need to do sign extend */
  12485. +           no_sign_extend = 1;
  12486. +         }
  12487. +       CC_STATUS_INIT;
  12488. +       if (no_sign_extend)
  12489. +         {
  12490. +       if (REGNO (operands[0]) == REGNO (operands[2]))
  12491. +         {
  12492. +               operands [0] = gen_rtx (REG, SImode, REGNO (operands[0]));
  12493. +           output_asm_insn (AS2 (and%L0,%1,%0), operands);
  12494. +         }
  12495. +       else
  12496. +         {
  12497. +           output_asm_insn (AS2 (and%W0,%1,%w0), operands);
  12498. +               operands [0] = gen_rtx (REG, SImode, REGNO (operands[0]));
  12499. +           output_asm_insn (AS2 (mov%L0,%0,%2), operands);
  12500. +           operands [1] = gen_rtx (CONST_INT, 0, 0xffff);
  12501. +           output_asm_insn (AS2 (and%L0,%1,%2), operands);
  12502. +         }
  12503. +       RET;
  12504. +         }
  12505. +       /* Can we ignore the upper byte? */
  12506. +       else if (QI_REG_P (operands[0])
  12507. +       && (INTVAL (operands[1]) & 0xff00) == 0xff00)
  12508. +     {
  12509. +       if ((INTVAL (operands[1]) & 0xff) == 0)
  12510. +         {
  12511. +           operands[1] = const0_rtx;
  12512. +           output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
  12513. +         }
  12514. +       else
  12515. +         {
  12516. +           operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
  12517. +           output_asm_insn (AS2 (and%B0,%1,%b0), operands);
  12518. +         }
  12519. +     }
  12520. +       else if (!no_sign_extend && QI_REG_P (operands[0]) 
  12521. +                && (INTVAL (operands[1]) & 0xff) == 0xff)
  12522. +     {
  12523. +       if ((INTVAL (operands[1]) & 0xff00) == 0)
  12524. +         {
  12525. +           operands[1] = const0_rtx;
  12526. +           output_asm_insn (AS2 (mov%B0,%1,%h0), operands);
  12527. +         }
  12528. +       operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff);
  12529. +       output_asm_insn (AS2 (and%B0,%1,%b0), operands);
  12530. +     }
  12531. +   if (REGNO (operands[2]) == 0 && REGNO (operands[0]) == 0)
  12532. + #ifdef INTEL_SYNTAX
  12533. +     return \"cwde\";
  12534. + #else
  12535. +     return \"cwtl\";
  12536. + #endif
  12537. + #ifdef INTEL_SYNTAX
  12538. +   return AS2 (movsx,%0,%2);
  12539. + #else
  12540. +   return AS2 (movs%W0%L0,%0,%2);
  12541. + #endif
  12542. + }");
  12543. + (define_peephole
  12544. +   [
  12545. +    (set (match_operand:HI 0 "register_operand" "")
  12546. +     (match_operand:HI 1 "memory_operand" ""))
  12547. +    (set (match_dup 0)
  12548. +     (and:HI (match_dup 0)
  12549. +         (match_operand:HI 2 "immediate_operand" "")))
  12550. +    (set (match_operand:SI 3 "register_operand" "")
  12551. +     (sign_extend:SI
  12552. +      (match_dup 0)))
  12553. +   ]
  12554. +   ""
  12555. +   "*
  12556. + {
  12557. +       int no_sign_extend = 0;
  12558. +       if ((INTVAL (operands[2]) & 0xff00) == 0
  12559. +           && QI_REG_P (operands[0]))
  12560. +         {
  12561. +           output_asm_insn (AS2 (mov%B0,%b1,%b0), operands);
  12562. +         }
  12563. +       else
  12564. +         {
  12565. +           output_asm_insn (AS2 (mov%W0,%1,%0), operands);
  12566. +         }
  12567. +       if ((INTVAL (operands[2]) & 0x8000) == 0)
  12568. +         { /* Don't need to do sign extend */
  12569. +           no_sign_extend = 1;
  12570. +         }
  12571. +       CC_STATUS_INIT;
  12572. +       if (no_sign_extend)
  12573. +         {
  12574. +       if (REGNO (operands[0]) == REGNO (operands[3]))
  12575. +         {
  12576. +               operands [0] = gen_rtx (REG, SImode, REGNO (operands[0]));
  12577. +           output_asm_insn (AS2 (and%L0,%2,%0), operands);
  12578. +         }
  12579. +       else
  12580. +         {
  12581. +           output_asm_insn (AS2 (and%W0,%2,%w0), operands);
  12582. +               operands [0] = gen_rtx (REG, SImode, REGNO (operands[0]));
  12583. +           output_asm_insn (AS2 (mov%L0,%0,%3), operands);
  12584. +           operands [2] = gen_rtx (CONST_INT, 0, 0xffff);
  12585. +           output_asm_insn (AS2 (and%L0,%2,%3), operands);
  12586. +         }
  12587. +       RET;
  12588. +         }
  12589. +       /* Can we ignore the upper byte? */
  12590. +       else if (QI_REG_P (operands[0])
  12591. +       && (INTVAL (operands[2]) & 0xff00) == 0xff00)
  12592. +     {
  12593. +       if ((INTVAL (operands[2]) & 0xff) == 0)
  12594. +         {
  12595. +           operands[2] = const0_rtx;
  12596. +           output_asm_insn (AS2 (mov%B0,%2,%b0), operands);
  12597. +         }
  12598. +       else
  12599. +         {
  12600. +           operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
  12601. +           output_asm_insn (AS2 (and%B0,%2,%b0), operands);
  12602. +         }
  12603. +     }
  12604. +       else if (!no_sign_extend && QI_REG_P (operands[0]) 
  12605. +                && (INTVAL (operands[2]) & 0xff) == 0xff)
  12606. +     {
  12607. +       if ((INTVAL (operands[2]) & 0xff00) == 0)
  12608. +         {
  12609. +           operands[2] = const0_rtx;
  12610. +           output_asm_insn (AS2 (mov%B0,%2,%h0), operands);
  12611. +         }
  12612. +       operands[1] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  12613. +       output_asm_insn (AS2 (and%B0,%2,%b0), operands);
  12614. +     }
  12615. +       else
  12616. +         {
  12617. +           output_asm_insn (AS2 (and%W0,%2,%0), operands);
  12618. +         }
  12619. +   if (REGNO (operands[3]) == 0 && REGNO (operands[0]) == 0)
  12620. + #ifdef INTEL_SYNTAX
  12621. +     return \"cwde\";
  12622. + #else
  12623. +     return \"cwtl\";
  12624. + #endif
  12625. + #ifdef INTEL_SYNTAX
  12626. +   return AS2 (movsx,%0,%3);
  12627. + #else
  12628. +   return AS2 (movs%W0%L0,%0,%3);
  12629. + #endif
  12630. + }");
  12631. + (define_peephole
  12632. +   [
  12633. +    (set (match_operand:HI 0 "register_operand" "")
  12634. +     (sign_extend:HI
  12635. +      (match_operand:QI 1 "memory_operand" "")))
  12636. +    (set (match_dup 0)
  12637. +     (and:HI (match_dup 0)
  12638. +         (match_operand:HI 2 "immediate_operand" "")))
  12639. +    (set (match_operand:SI 3 "register_operand" "")
  12640. +     (sign_extend:SI
  12641. +      (match_dup 0)))
  12642. +   ]
  12643. +   ""
  12644. +   "*
  12645. + {
  12646. +       int no_sign_extend = 0;
  12647. +       if ((INTVAL (operands[2]) & 0xff00) == 0
  12648. +           && QI_REG_P (operands[0]))
  12649. +         {
  12650. +           output_asm_insn (AS2 (mov%B0,%b1,%b0), operands);
  12651. +         }
  12652. +       else
  12653. +         {
  12654. + #ifdef INTEL_SYNTAX
  12655. +           output_asm_insn( AS2 (movsx,%1,%0), operands);
  12656. + #else
  12657. +           output_asm_insn( AS2 (movs%B0%W0,%1,%0), operands);
  12658. + #endif
  12659. +         }
  12660. +       if ((INTVAL (operands[2]) & 0x8000) == 0)
  12661. +         { /* Don't need to do sign extend */
  12662. +           no_sign_extend = 1;
  12663. +         }
  12664. +       CC_STATUS_INIT;
  12665. +       if (no_sign_extend)
  12666. +         {
  12667. +       if (REGNO (operands[0]) == REGNO (operands[3]))
  12668. +         {
  12669. +               operands [0] = gen_rtx (REG, SImode, REGNO (operands[0]));
  12670. +           output_asm_insn (AS2 (and%L0,%2,%0), operands);
  12671. +         }
  12672. +       else
  12673. +         {
  12674. +           output_asm_insn (AS2 (and%W0,%2,%w0), operands);
  12675. +               operands [0] = gen_rtx (REG, SImode, REGNO (operands[0]));
  12676. +           output_asm_insn (AS2 (mov%L0,%0,%3), operands);
  12677. +           operands [2] = gen_rtx (CONST_INT, 0, 0xffff);
  12678. +           output_asm_insn (AS2 (and%L0,%2,%3), operands);
  12679. +         }
  12680. +       RET;
  12681. +         }
  12682. +       /* Can we ignore the upper byte? */
  12683. +       else if (QI_REG_P (operands[0])
  12684. +       && (INTVAL (operands[2]) & 0xff00) == 0xff00)
  12685. +     {
  12686. +       if ((INTVAL (operands[2]) & 0xff) == 0)
  12687. +         {
  12688. +           operands[2] = const0_rtx;
  12689. +           output_asm_insn (AS2 (mov%B0,%2,%b0), operands);
  12690. +         }
  12691. +       else
  12692. +         {
  12693. +           operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
  12694. +           output_asm_insn (AS2 (and%B0,%2,%b0), operands);
  12695. +         }
  12696. +     }
  12697. +       else if (!no_sign_extend && QI_REG_P (operands[0]) 
  12698. +                && (INTVAL (operands[2]) & 0xff) == 0xff)
  12699. +     {
  12700. +       if ((INTVAL (operands[2]) & 0xff00) == 0)
  12701. +         {
  12702. +           operands[2] = const0_rtx;
  12703. +           output_asm_insn (AS2 (mov%B0,%2,%h0), operands);
  12704. +         }
  12705. +       operands[1] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  12706. +       output_asm_insn (AS2 (and%B0,%2,%b0), operands);
  12707. +     }
  12708. +       else
  12709. +         {
  12710. +           output_asm_insn (AS2 (and%W0,%2,%0), operands);
  12711. +         }
  12712. +   if (REGNO (operands[3]) == 0 && REGNO (operands[0]) == 0)
  12713. + #ifdef INTEL_SYNTAX
  12714. +     return \"cwde\";
  12715. + #else
  12716. +     return \"cwtl\";
  12717. + #endif
  12718. + #ifdef INTEL_SYNTAX
  12719. +   return AS2 (movsx,%0,%3);
  12720. + #else
  12721. +   return AS2 (movs%W0%L0,%0,%3);
  12722. + #endif
  12723. + }");
  12724. + (define_peephole
  12725. +   [
  12726. +    (set (match_operand:HI 0 "register_operand" "")
  12727. +     (sign_extend:HI
  12728. +      (match_operand:QI 1 "memory_operand" "")))
  12729. +    (set (match_dup 0)
  12730. +     (and:HI (match_dup 0)
  12731. +         (match_operand:HI 2 "immediate_operand" "")))
  12732. +   ]
  12733. +   ""
  12734. +   "*
  12735. + {
  12736. +       if ((INTVAL (operands[2]) & 0xff00) == 0
  12737. +           && QI_REG_P (operands[0]))
  12738. +         {
  12739. +           output_asm_insn (AS2 (mov%B0,%b1,%b0), operands);
  12740. +         }
  12741. +       else
  12742. +         {
  12743. + #ifdef INTEL_SYNTAX
  12744. +           output_asm_insn( AS2 (movsx,%1,%0), operands);
  12745. + #else
  12746. +           output_asm_insn( AS2 (movs%B0%W0,%1,%0), operands);
  12747. + #endif
  12748. +         }
  12749. +       /* Can we ignore the upper byte? */
  12750. +       if (QI_REG_P (operands[0])
  12751. +       && (INTVAL (operands[2]) & 0xff00) == 0xff00)
  12752. +     {
  12753. +       if ((INTVAL (operands[2]) & 0xff) == 0)
  12754. +         {
  12755. +           operands[2] = const0_rtx;
  12756. +           output_asm_insn (AS2 (mov%B0,%2,%b0), operands);
  12757. +         }
  12758. +       else
  12759. +         {
  12760. +           operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
  12761. +           output_asm_insn (AS2 (and%B0,%2,%b0), operands);
  12762. +         }
  12763. +     }
  12764. +       else if (QI_REG_P (operands[0]) 
  12765. +                && (INTVAL (operands[2]) & 0xff) == 0xff)
  12766. +     {
  12767. +       if ((INTVAL (operands[2]) & 0xff00) == 0)
  12768. +         {
  12769. +           operands[2] = const0_rtx;
  12770. +           output_asm_insn (AS2 (mov%B0,%2,%h0), operands);
  12771. +         }
  12772. +       operands[1] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  12773. +       output_asm_insn (AS2 (and%B0,%2,%b0), operands);
  12774. +     }
  12775. +       else
  12776. +         {
  12777. +           output_asm_insn (AS2 (and%W0,%2,%0), operands);
  12778. +         }
  12779. +    RET;
  12780. + }");
  12781. + (define_peephole
  12782. +   [
  12783. +    (set (match_operand:SI 0 "register_operand" "")
  12784. +     (sign_extend:SI
  12785. +      (match_operand:QI 1 "memory_operand" "")))
  12786. +    (set (match_dup 0)
  12787. +     (and:SI (match_dup 0)
  12788. +         (match_operand:SI 2 "immediate_operand" "")))
  12789. +   ]
  12790. +   ""
  12791. +   "*
  12792. + {
  12793. +       if ((INTVAL (operands[2]) & 0xffffff00) == 0
  12794. +           && QI_REG_P (operands[0]))
  12795. +         {
  12796. +           output_asm_insn (AS2 (mov%B0,%b1,%b0), operands);
  12797. +         }
  12798. +       else
  12799. +         {
  12800. + #ifdef INTEL_SYNTAX
  12801. +           output_asm_insn( AS2 (movsx,%1,%0), operands);
  12802. + #else
  12803. +           output_asm_insn( AS2 (movs%B0%L0,%1,%0), operands);
  12804. + #endif
  12805. +         }
  12806. +       output_asm_insn (AS2 (and%L0,%2,%0), operands);
  12807. +    RET;
  12808. + }");
  12809. + (define_peephole
  12810. +   [
  12811. +    (set (match_operand:SI 0 "register_operand" "")
  12812. +     (sign_extend:SI
  12813. +      (match_operand:HI 1 "memory_operand" "")))
  12814. +    (set (match_dup 0)
  12815. +     (and:SI (match_dup 0)
  12816. +         (match_operand:SI 2 "immediate_operand" "")))
  12817. +   ]
  12818. +   ""
  12819. +   "*
  12820. + {
  12821. +       if ((INTVAL (operands[2]) & 0xffffff00) == 0
  12822. +           && QI_REG_P (operands[0]))
  12823. +         {
  12824. +           output_asm_insn (AS2 (mov%B0,%b1,%b0), operands);
  12825. +         }
  12826. +       else if ((INTVAL (operands[2]) & 0xffff0000) == 0)
  12827. +         {
  12828. +           output_asm_insn (AS2 (mov%W0,%h1,%h0), operands);
  12829. +         }
  12830. +       else
  12831. +         {
  12832. + #ifdef INTEL_SYNTAX
  12833. +           output_asm_insn( AS2 (movsx,%1,%0), operands);
  12834. + #else
  12835. +           output_asm_insn( AS2 (movs%B0%W0,%1,%0), operands);
  12836. + #endif
  12837. +         }
  12838. +       output_asm_insn (AS2 (and%L0,%2,%0), operands);
  12839. +    RET;
  12840. + }");
  12841. diff -rNci gcc-2.7.2/config.sub gcc-2.7.2p/config.sub
  12842. *** gcc-2.7.2/config.sub    Thu Jun 15 21:01:49 1995
  12843. --- gcc-2.7.2p/config.sub    Tue Jan 23 09:25:24 1996
  12844. ***************
  12845. *** 130,141 ****
  12846.       # Recognize the basic CPU types without company name.
  12847.       # Some are omitted here because they have special meanings below.
  12848.       tahoe | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm \
  12849. !         | arme[lb] | pyramid \
  12850.           | tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \
  12851.           | alpha | we32k | ns16k | clipper | sparclite | i370 | sh \
  12852.           | powerpc | powerpcle | sparc64 | 1750a | dsp16xx | mips64 | mipsel \
  12853.           | pdp11 | mips64el | mips64orion | mips64orionel \
  12854. !         | sparc)
  12855.           basic_machine=$basic_machine-unknown
  12856.           ;;
  12857.       # Object if more than one company name word.
  12858. --- 130,141 ----
  12859.       # Recognize the basic CPU types without company name.
  12860.       # Some are omitted here because they have special meanings below.
  12861.       tahoe | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm \
  12862. !         | pentium | arme[lb] | pyramid \
  12863.           | tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \
  12864.           | alpha | we32k | ns16k | clipper | sparclite | i370 | sh \
  12865.           | powerpc | powerpcle | sparc64 | 1750a | dsp16xx | mips64 | mipsel \
  12866.           | pdp11 | mips64el | mips64orion | mips64orionel \
  12867. !         | sparc )
  12868.           basic_machine=$basic_machine-unknown
  12869.           ;;
  12870.       # Object if more than one company name word.
  12871. ***************
  12872. *** 145,157 ****
  12873.           ;;
  12874.       # Recognize the basic CPU types with company name.
  12875.       vax-* | tahoe-* | i[345]86-* | i860-* | m68k-* | m68000-* | m88k-* \
  12876. !           | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \
  12877.             | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
  12878.             | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
  12879.             | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
  12880.             | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
  12881.             | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \
  12882. !           | mips64el-* | mips64orion-* | mips64orionel-*)
  12883.           ;;
  12884.       # Recognize the various machine names and aliases which stand
  12885.       # for a CPU type and a company and sometimes even an OS.
  12886. --- 145,157 ----
  12887.           ;;
  12888.       # Recognize the basic CPU types with company name.
  12889.       vax-* | tahoe-* | i[345]86-* | i860-* | m68k-* | m68000-* | m88k-* \
  12890. !           | pentium-* | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \
  12891.             | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
  12892.             | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
  12893.             | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
  12894.             | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
  12895.             | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \
  12896. !           | mips64el-* | mips64orion-* | mips64orionel-* )
  12897.           ;;
  12898.       # Recognize the various machine names and aliases which stand
  12899.       # for a CPU type and a company and sometimes even an OS.
  12900. ***************
  12901. *** 312,329 ****
  12902. --- 312,345 ----
  12903.           basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
  12904.           os=-sysv32
  12905.           ;;
  12906. +     pentiumv32)
  12907. +         basic_machine=`echo $1 | sed -e 's/pentium.*/pentium-unknown/'`
  12908. +         os=-sysv32
  12909. +         ;;
  12910.       i[345]86v4*)
  12911.           basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
  12912.           os=-sysv4
  12913.           ;;
  12914. +   pentiumv4*)
  12915. +       basic_machine=`echo $1 | sed -e 's/pentium.*/pentium-unknown/'`
  12916. +       os=-sysv4
  12917. +       ;;
  12918.       i[345]86v)
  12919.           basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
  12920.           os=-sysv
  12921.           ;;
  12922. +   pentiumv)
  12923. +       basic_machine=`echo $1 | sed -e 's/pentium.*/pentium-unknown/'`
  12924. +       os=-sysv
  12925. +       ;;
  12926.       i[345]86sol2)
  12927.           basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
  12928.           os=-solaris2
  12929.           ;;
  12930. +   pentiumsol2)
  12931. +       basic_machine=`echo $1 | sed -e 's/pentium.*/pentium-unknown/'`
  12932. +       os=-solaris2
  12933. +       ;;
  12934.       iris | iris4d)
  12935.           basic_machine=mips-sgi
  12936.           case $os in
  12937. diff -rNci gcc-2.7.2/configure gcc-2.7.2p/configure
  12938. *** gcc-2.7.2/configure    Sun Nov 26 19:39:15 1995
  12939. --- gcc-2.7.2p/configure    Tue Jan 23 09:53:19 1996
  12940. ***************
  12941. *** 844,850 ****
  12942.           xm_file=i370/xm-mvs.h
  12943.           out_file=i370/mvs370.c
  12944.           ;;
  12945. !     i[345]86-ibm-aix*)        # IBM PS/2 running AIX
  12946.           cpu_type=i386
  12947.                   if [ x$gas = xyes ]
  12948.           then
  12949. --- 844,850 ----
  12950.           xm_file=i370/xm-mvs.h
  12951.           out_file=i370/mvs370.c
  12952.           ;;
  12953. !     pentium-ibm-aix* | i[345]86-ibm-aix*)        # IBM PS/2 running AIX
  12954.           cpu_type=i386
  12955.                   if [ x$gas = xyes ]
  12956.           then
  12957. ***************
  12958. *** 867,873 ****
  12959.           extra_parts="crtbegin.o crtend.o"
  12960.           tmake_file=i386/t-crtpic
  12961.           ;;
  12962. !     i[345]86-next-*)
  12963.           cpu_type=i386
  12964.           tm_file=i386/next.h
  12965.           out_file=i386/next.c
  12966. --- 867,873 ----
  12967.           extra_parts="crtbegin.o crtend.o"
  12968.           tmake_file=i386/t-crtpic
  12969.           ;;
  12970. !     pentium-next-* | i[345]86-next-*)
  12971.           cpu_type=i386
  12972.           tm_file=i386/next.h
  12973.           out_file=i386/next.c
  12974. ***************
  12975. *** 875,881 ****
  12976.           tmake_file=i386/t-next
  12977.           xmake_file=i386/x-next
  12978.           ;;
  12979. !     i[345]86-sequent-bsd*)         # 80386 from Sequent
  12980.           cpu_type=i386
  12981.           use_collect2=yes
  12982.           if [ x$gas = xyes ]
  12983. --- 875,881 ----
  12984.           tmake_file=i386/t-next
  12985.           xmake_file=i386/x-next
  12986.           ;;
  12987. !     pentium-sequent-bsd* | i[345]86-sequent-bsd*)         # 80386 from Sequent
  12988.           cpu_type=i386
  12989.           use_collect2=yes
  12990.           if [ x$gas = xyes ]
  12991. ***************
  12992. *** 885,891 ****
  12993.               tm_file=i386/sequent.h
  12994.           fi
  12995.           ;;
  12996. !     i[345]86-sequent-ptx1*)
  12997.           cpu_type=i386
  12998.           xm_file=i386/xm-sysv3.h
  12999.           xmake_file=i386/x-sysv3
  13000. --- 885,891 ----
  13001.               tm_file=i386/sequent.h
  13002.           fi
  13003.           ;;
  13004. !     pentium-sequent-ptx1* | i[345]86-sequent-ptx1*)
  13005.           cpu_type=i386
  13006.           xm_file=i386/xm-sysv3.h
  13007.           xmake_file=i386/x-sysv3
  13008. ***************
  13009. *** 912,928 ****
  13010.           tm_file=i386/sun.h
  13011.           use_collect2=yes
  13012.           ;;
  13013.       i[345]86-*-aout*)
  13014.           cpu_type=i386
  13015.           tm_file=i386/i386-aout.h
  13016.           tmake_file=i386/t-i386bare
  13017.           ;;
  13018. -     i[345]86-*-bsdi* | i[345]86-*-bsd386*)
  13019. -         cpu_type=i386
  13020. -         tm_file=i386/bsd386.h
  13021. -         xm_file=i386/xm-bsd386.h
  13022. - #        tmake_file=t-libc-ok
  13023. -         ;;
  13024.       i[345]86-*-bsd*)
  13025.           cpu_type=i386
  13026.           tm_file=i386/386bsd.h
  13027. --- 912,927 ----
  13028.           tm_file=i386/sun.h
  13029.           use_collect2=yes
  13030.           ;;
  13031. +     pentium-*-bsd* | i[345]86-*-bsdi* | i[345]86-*-bsd386*)
  13032. +         cpu_type=i386
  13033. +         tm_file=i386/bsd386.h
  13034. + #        tmake_file=t-libc-ok
  13035. +         ;;
  13036.       i[345]86-*-aout*)
  13037.           cpu_type=i386
  13038.           tm_file=i386/i386-aout.h
  13039.           tmake_file=i386/t-i386bare
  13040.           ;;
  13041.       i[345]86-*-bsd*)
  13042.           cpu_type=i386
  13043.           tm_file=i386/386bsd.h
  13044. ***************
  13045. *** 931,960 ****
  13046.   # Next line turned off because both 386BSD and BSD/386 use GNU ld.
  13047.   #        use_collect2=yes
  13048.           ;;
  13049. !     i[345]86-*-freebsd*)
  13050.           cpu_type=i386
  13051.           tm_file=i386/freebsd.h
  13052. -         xm_file=i386/xm-freebsd.h
  13053.           # On FreeBSD, the headers are already ok.
  13054.           fixincludes=Makefile.in
  13055.           xmake_file=i386/x-freebsd
  13056.           ;;
  13057. !     i[345]86-*-netbsd*)
  13058.           cpu_type=i386
  13059. !         tm_file=i386/netbsd.h
  13060. !         xm_file=i386/xm-netbsd.h
  13061.           # On NetBSD, the headers are already okay.
  13062.           fixincludes=Makefile.in
  13063. -         tmake_file=t-libc-ok
  13064.           xmake_file=x-netbsd
  13065.           ;;
  13066. !     i[345]86-*-coff*)
  13067.           cpu_type=i386
  13068. !         tm_file=i386/i386-coff.h
  13069. !         tmake_file=i386/t-i386bare
  13070. !         ;;
  13071. !     i[345]86-*-gnu*)
  13072. !         cpu_type=i386    # GNU supports this CPU; rest done below.
  13073.           ;;
  13074.       i[345]86-*-isc*)        # 80386 running ISC system
  13075.           cpu_type=i386
  13076. --- 930,959 ----
  13077.   # Next line turned off because both 386BSD and BSD/386 use GNU ld.
  13078.   #        use_collect2=yes
  13079.           ;;
  13080. !     pentium-*-freebsd* | i[345]86-*-freebsd*)
  13081.           cpu_type=i386
  13082.           tm_file=i386/freebsd.h
  13083.           # On FreeBSD, the headers are already ok.
  13084.           fixincludes=Makefile.in
  13085.           xmake_file=i386/x-freebsd
  13086.           ;;
  13087. !     pentium-*-netbsd* | i[345]86-*-netbsd*)
  13088.           cpu_type=i386
  13089. !         tm_file=i386/netbsd-i386.h
  13090.           # On NetBSD, the headers are already okay.
  13091.           fixincludes=Makefile.in
  13092.           xmake_file=x-netbsd
  13093.           ;;
  13094. !     pentium-*-gnu* | i[345]86-*-gnu*)
  13095.           cpu_type=i386
  13096. !         xm_file=i386/xm-gnu.h
  13097. !         tm_file=i386/gnu.h
  13098. !         tmake_file=t-libc-ok
  13099. !         # GNU tools are the only tools.
  13100. !         gnu_ld=yes
  13101. !         gas=yes
  13102. !         # On GNU, the headers are already okay.
  13103. !         fixincludes=Makefile.in
  13104.           ;;
  13105.       i[345]86-*-isc*)        # 80386 running ISC system
  13106.           cpu_type=i386
  13107. ***************
  13108. *** 972,1021 ****
  13109.           then
  13110.               tm_file=i386/iscdbx.h
  13111.               tmake_file=i386/t-svr3dbx
  13112. -             extra_parts="crtbegin.o crtend.o svr3.ifile svr3z.ifile"
  13113.           else
  13114.               tm_file=i386/isccoff.h
  13115. -             tmake_file=i386/t-crtstuff
  13116.               extra_parts="crtbegin.o crtend.o"
  13117.           fi
  13118.           install_headers_dir=install-headers-cpio
  13119.           broken_install=yes
  13120.           ;;
  13121. !     i[345]86-*-linux*oldld*)    # Intel 80386's running Linux
  13122. !         cpu_type=i386        # with a.out format using pre BFD linkers
  13123. !         xm_file=i386/xm-linux.h
  13124. !         xmake_file=x-linux
  13125. !         tm_file=i386/linux-oldld.h
  13126. !         fixincludes=Makefile.in #On Linux, the headers are ok already.
  13127. !         broken_install=yes
  13128. !         gnu_ld=yes
  13129. !         ;;
  13130. !     i[345]86-*-linux*aout*)        # Intel 80386's running Linux
  13131. !         cpu_type=i386        # with a.out format
  13132.           xm_file=i386/xm-linux.h
  13133. !         xmake_file=x-linux
  13134.           tm_file=i386/linux-aout.h
  13135.           fixincludes=Makefile.in #On Linux, the headers are ok already.
  13136.           broken_install=yes
  13137. -         gnu_ld=yes
  13138.           ;;
  13139. !     i[345]86-*-linux*)        # Intel 80386's running Linux
  13140. !         cpu_type=i386        # with ELF format
  13141.           xm_file=i386/xm-linux.h
  13142. !         xmake_file=x-linux
  13143.           tm_file=i386/linux.h
  13144.           fixincludes=Makefile.in #On Linux, the headers are ok already.
  13145.           broken_install=yes
  13146. -         gnu_ld=yes
  13147. -         # Don't use it. Linux uses a slightly different one.
  13148. -         # The real one comes with the Linux C library.
  13149. -         #extra_parts="crtbegin.o crtend.o"
  13150.           ;;
  13151. !       i[345]86-go32-msdos | i[345]86-*-go32)
  13152. !               cpu_type=i386
  13153. !               tm_file=i386/go32.h
  13154. !               ;;
  13155. !     i[345]86-*-lynxos*)
  13156.           cpu_type=i386
  13157.           if [ x$gas = xyes ]
  13158.           then
  13159. --- 971,1000 ----
  13160.           then
  13161.               tm_file=i386/iscdbx.h
  13162.               tmake_file=i386/t-svr3dbx
  13163.           else
  13164.               tm_file=i386/isccoff.h
  13165.               extra_parts="crtbegin.o crtend.o"
  13166.           fi
  13167.           install_headers_dir=install-headers-cpio
  13168.           broken_install=yes
  13169.           ;;
  13170. !     pentium-*-linuxaout | i[345]86-*-linuxaout)        # Intel 80386's running Linux
  13171. !         cpu_type=i386
  13172.           xm_file=i386/xm-linux.h
  13173. !         xmake_file=i386/x-linux
  13174.           tm_file=i386/linux-aout.h
  13175.           fixincludes=Makefile.in #On Linux, the headers are ok already.
  13176.           broken_install=yes
  13177.           ;;
  13178. !     pentium-*-linux* | i[345]86-*-linux*)        # Intel 80386's running Linux
  13179. !         cpu_type=i386
  13180.           xm_file=i386/xm-linux.h
  13181. !         xmake_file=i386/x-linux
  13182.           tm_file=i386/linux.h
  13183.           fixincludes=Makefile.in #On Linux, the headers are ok already.
  13184.           broken_install=yes
  13185.           ;;
  13186. !     pentium-*-lynxos* | i[345]86-*-lynxos*)
  13187.           cpu_type=i386
  13188.           if [ x$gas = xyes ]
  13189.           then
  13190. ***************
  13191. *** 1027,1039 ****
  13192.           tmake_file=i386/t-i386bare
  13193.           xmake_file=x-lynx
  13194.           ;;
  13195. !     i[345]86-*-mach*)
  13196.           cpu_type=i386
  13197.           tm_file=i386/mach.h
  13198.   #        tmake_file=t-libc-ok
  13199.           use_collect2=yes
  13200.           ;;
  13201. !     i[345]86-*-osfrose*)        # 386 using OSF/rose
  13202.           cpu_type=i386
  13203.                   if [ x$elf = xyes ]
  13204.           then
  13205. --- 1006,1018 ----
  13206.           tmake_file=i386/t-i386bare
  13207.           xmake_file=x-lynx
  13208.           ;;
  13209. !     pentium-*-mach* | i[345]86-*-mach*)
  13210.           cpu_type=i386
  13211.           tm_file=i386/mach.h
  13212.   #        tmake_file=t-libc-ok
  13213.           use_collect2=yes
  13214.           ;;
  13215. !     pentium-*-osfrose* | i[345]86-*-osfrose*)        # 386 using OSF/rose
  13216.           cpu_type=i386
  13217.                   if [ x$elf = xyes ]
  13218.           then
  13219. ***************
  13220. *** 1093,1099 ****
  13221.           fixincludes=fixinc.svr4
  13222.           broken_install=yes
  13223.           ;;
  13224. !     i[345]86-*-sysv4*)        # Intel 80386's running system V.4
  13225.           cpu_type=i386
  13226.           xm_file=i386/xm-sysv4.h
  13227.           if [ x$stabs = xyes ]
  13228. --- 1072,1078 ----
  13229.           fixincludes=fixinc.svr4
  13230.           broken_install=yes
  13231.           ;;
  13232. !     pentium-*-sysv4* | i[345]86-*-sysv4*)    # Intel 80386's running system V.4
  13233.           cpu_type=i386
  13234.           xm_file=i386/xm-sysv4.h
  13235.           if [ x$stabs = xyes ]
  13236. ***************
  13237. *** 1106,1112 ****
  13238.           xmake_file=x-svr4
  13239.           extra_parts="crtbegin.o crtend.o"
  13240.           ;;
  13241. !     i[345]86-*-sysv*)        # Intel 80386's running system V
  13242.           cpu_type=i386
  13243.           xm_file=i386/xm-sysv3.h
  13244.           xmake_file=i386/x-sysv3
  13245. --- 1085,1091 ----
  13246.           xmake_file=x-svr4
  13247.           extra_parts="crtbegin.o crtend.o"
  13248.           ;;
  13249. !     pentium-*-sysv* | i[345]86-*-sysv*)        # Intel 80386's running system V
  13250.           cpu_type=i386
  13251.           xm_file=i386/xm-sysv3.h
  13252.           xmake_file=i386/x-sysv3
  13253. ***************
  13254. *** 1116,1152 ****
  13255.               then
  13256.                   tm_file=i386/svr3dbx.h
  13257.                   tmake_file=i386/t-svr3dbx
  13258. -                 extra_parts="svr3.ifile svr3z.rfile"
  13259.               else
  13260.                   tm_file=i386/svr3gas.h
  13261.                   extra_parts="crtbegin.o crtend.o"
  13262. -                 tmake_file=i386/t-crtstuff
  13263.               fi
  13264.           else
  13265.               tm_file=i386/sysv3.h
  13266.               extra_parts="crtbegin.o crtend.o"
  13267. -             tmake_file=i386/t-crtstuff
  13268.           fi
  13269.           ;;
  13270. !     i386-*-vsta)            # Intel 80386's running VSTa kernel
  13271. !         xm_file=i386/xm-vsta.h
  13272. !         tm_file=i386/vsta.h
  13273. !         tmake_file=i386/t-vsta
  13274. !         xmake_file=i386/x-vsta
  13275. !         ;;
  13276. !     i[345]86-*-winnt3*)
  13277.           cpu_type=i386
  13278. !         tm_file=i386/win-nt.h
  13279.           out_file=i386/i386.c
  13280.           xm_file=i386/xm-winnt.h
  13281. !         xmake_file=winnt/x-winnt
  13282. !         tmake_file=i386/t-winnt
  13283. !         extra_objs="winnt.o oldnames.o"
  13284. !         extra_gcc_objs="spawnv.o oldnames.o"
  13285. !         fixincludes=fixinc.winnt
  13286.           if [ x$gnu_ld != xyes ]
  13287.           then
  13288. !             extra_programs=ld.exe
  13289.           fi
  13290.           ;;
  13291.       i860-alliant-*)        # Alliant FX/2800
  13292. --- 1095,1118 ----
  13293.               then
  13294.                   tm_file=i386/svr3dbx.h
  13295.                   tmake_file=i386/t-svr3dbx
  13296.               else
  13297.                   tm_file=i386/svr3gas.h
  13298.                   extra_parts="crtbegin.o crtend.o"
  13299.               fi
  13300.           else
  13301.               tm_file=i386/sysv3.h
  13302.               extra_parts="crtbegin.o crtend.o"
  13303.           fi
  13304.           ;;
  13305. !     pentium-*-winnt3* | i[345]86-*-winnt3*)
  13306.           cpu_type=i386
  13307. !         tm_file=i386/winnt.h
  13308.           out_file=i386/i386.c
  13309.           xm_file=i386/xm-winnt.h
  13310. !         xmake_file=i386/x-winnt
  13311.           if [ x$gnu_ld != xyes ]
  13312.           then
  13313. !             extra_programs=ld
  13314.           fi
  13315.           ;;
  13316.       i860-alliant-*)        # Alliant FX/2800
  13317. ***************
  13318. *** 2411,2420 ****
  13319.       esac
  13320.   
  13321.       # Distinguish i386 from i486/i586.
  13322. !     # ??? For the moment we treat i586 as an i486.
  13323.       # Also, do not run mips-tfile on MIPS if using gas.
  13324.       case $machine in
  13325. !     i[45]86-*-*)
  13326.           target_cpu_default=2
  13327.           ;;
  13328.       mips*-*-*)
  13329. --- 2377,2392 ----
  13330.       esac
  13331.   
  13332.       # Distinguish i386 from i486/i586.
  13333. !     # ??? For the moment we treat i586 as an i486. (NOT!)
  13334.       # Also, do not run mips-tfile on MIPS if using gas.
  13335.       case $machine in
  13336. !     pentium-*-*)
  13337. !         target_cpu_default=4
  13338. !         ;;
  13339. !     i586-*-*)
  13340. !         target_cpu_default=4
  13341. !         ;;
  13342. !     i486-*-*)
  13343.           target_cpu_default=2
  13344.           ;;
  13345.       mips*-*-*)
  13346. diff -rNci gcc-2.7.2/cse.c gcc-2.7.2p/cse.c
  13347. *** gcc-2.7.2/cse.c    Sun Nov 26 19:47:05 1995
  13348. --- gcc-2.7.2p/cse.c    Tue Jan 23 09:53:20 1996
  13349. ***************
  13350. *** 6136,6141 ****
  13351. --- 6136,6164 ----
  13352.         sets = (struct set *) alloca (sizeof (struct set));
  13353.         sets[0].rtl = x;
  13354.   
  13355. + /* intel1 */
  13356. + #ifdef STACK_REGS
  13357. + #ifdef IS_STACK_MODE
  13358. +       if (IS_STACK_MODE (DFmode) && GET_CODE (SET_SRC (x)) == CONST_DOUBLE 
  13359. +          && GET_CODE (SET_DEST (x)) == REG)
  13360. +         {
  13361. +            /* not worthwhile to hold on stack */
  13362. +       rtx tem = find_reg_note (insn, REG_EQUAL, 0);
  13363. +       
  13364. +       /* Record the actual constant value in a REG_EQUAL note, making
  13365. +          a new one if one does not already exist.  */
  13366. +       if (tem)
  13367. +         XEXP (tem, 0) = SET_SRC(x);
  13368. +       else
  13369. +         REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
  13370. +                         SET_SRC(x), REG_NOTES (insn));
  13371. +       invalidate (SET_DEST (x), GET_MODE(x) );
  13372. +         }
  13373. +       else
  13374. +       
  13375. + #endif
  13376. + #endif
  13377.         /* Ignore SETs that are unconditional jumps.
  13378.        They never need cse processing, so this does not hurt.
  13379.        The reason is not efficiency but rather
  13380. ***************
  13381. *** 6762,6767 ****
  13382. --- 6785,6816 ----
  13383.         if (dest == pc_rtx && src_const && GET_CODE (src_const) == LABEL_REF)
  13384.       src_folded = src_const, src_folded_cost = -1;
  13385.         
  13386. + #ifdef SAVE_ON_REGS
  13387. +       /* intel1 If src is of form  (reg1 OP const) and src_folded
  13388. +          is of form (reg2 OP const) and the costs are the same
  13389. +          and reg1 != reg2,
  13390. +          then bump up the cost of src_folded so that src will be
  13391. +          preferred.  The reason for this is that if reg2 is used
  13392. +          here it's life may be extended thereby increasing register
  13393. +          pressure and causing superfulous movs.  */
  13394. +       {
  13395. +         char * fmt;
  13396. +         if (src)
  13397. +           fmt = GET_RTX_FORMAT (GET_CODE (src));
  13398. +         if (src && src_folded && src_cost == src_folded_cost
  13399. +             && GET_CODE (src) == GET_CODE (src_folded) 
  13400. +             && GET_RTX_LENGTH (GET_CODE (src)) == 2
  13401. +             && fmt[0] == 'e' && fmt[1] == 'e'
  13402. +             && GET_CODE (XEXP (src, 0)) == REG
  13403. +             && GET_CODE (XEXP (src, 1)) == CONST_INT 
  13404. +             && GET_CODE (XEXP (src_folded, 0)) == REG
  13405. +             && GET_CODE (XEXP (src_folded, 1)) == CONST_INT 
  13406. +             && !rtx_equal_p (XEXP (src, 0), XEXP (src_folded, 0)))
  13407. +           {
  13408. +             src_folded_cost++;
  13409. +           }          
  13410. +       }
  13411. + #endif
  13412.         /* Terminate loop when replacement made.  This must terminate since
  13413.            the current contents will be tested and will always be valid.  */
  13414.         while (1)
  13415. ***************
  13416. *** 7205,7210 ****
  13417. --- 7254,7269 ----
  13418.           if (sets[i].src_elt == 0)
  13419.             {
  13420.           register struct table_elt *elt;
  13421. +         /* intel1 */
  13422. +         int do_rehash=0;
  13423. +                 /* intel1 */
  13424. +         if(GET_CODE(src)==REG && 
  13425. +            !REGNO_QTY_VALID_P (REGNO(src)))
  13426. +             { /* we will want to rehash all expressions based of src since
  13427. +                  reg_qty[REGNO(src)] is about to change */
  13428. +               do_rehash = 1;
  13429. +             }
  13430.   
  13431.           /* Note that these insert_regs calls cannot remove
  13432.              any of the src_elt's, because they would have failed to
  13433. diff -rNci gcc-2.7.2/expr.c gcc-2.7.2p/expr.c
  13434. *** gcc-2.7.2/expr.c    Sun Nov 26 16:18:07 1995
  13435. --- gcc-2.7.2p/expr.c    Tue Jan 23 09:53:21 1996
  13436. ***************
  13437. *** 24,29 ****
  13438. --- 24,31 ----
  13439.   #include "rtl.h"
  13440.   #include "tree.h"
  13441.   #include "obstack.h"
  13442. + /* intel1 */
  13443. + #include "c-tree.h"
  13444.   #include "flags.h"
  13445.   #include "regs.h"
  13446.   #include "function.h"
  13447. ***************
  13448. *** 8954,8959 ****
  13449. --- 8956,8967 ----
  13450.         && (i = floor_log2 (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)))) >= 0
  13451.         && (mode = mode_for_size (i + 1, MODE_INT, 0)) != BLKmode
  13452.         && (type = type_for_mode (mode, 1)) != 0
  13453. +       /* intel1 */
  13454. +       && !(SLOW_SHORT_ACCESS
  13455. +          && (type == short_unsigned_type_node
  13456. +              || type == short_integer_type_node
  13457. +              || type == intHI_type_node
  13458. +              || type == unsigned_intHI_type_node))
  13459.         && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
  13460.         && (cmp_optab->handlers[(int) TYPE_MODE (type)].insn_code
  13461.             != CODE_FOR_nothing))
  13462. ***************
  13463. *** 9111,9116 ****
  13464. --- 9119,9130 ----
  13465.       type = type_for_size (bitsize, unsignedp);
  13466.       if (! SLOW_BYTE_ACCESS
  13467.           && type != 0 && bitsize >= 0
  13468. +         /* intel1 */
  13469. +         && !(SLOW_SHORT_ACCESS 
  13470. +              && (type == short_unsigned_type_node 
  13471. +                  || type == short_integer_type_node
  13472. +                  || type == intHI_type_node 
  13473. +                  || type == unsigned_intHI_type_node))
  13474.           && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
  13475.           && (cmp_optab->handlers[(int) TYPE_MODE (type)].insn_code
  13476.           != CODE_FOR_nothing))
  13477. diff -rNci gcc-2.7.2/flags.h gcc-2.7.2p/flags.h
  13478. *** gcc-2.7.2/flags.h    Thu Jun 15 11:34:11 1995
  13479. --- gcc-2.7.2p/flags.h    Tue Jan 23 09:25:25 1996
  13480. ***************
  13481. *** 361,363 ****
  13482. --- 361,509 ----
  13483.      function.  */
  13484.   
  13485.   extern int current_function_has_nonlocal_goto;
  13486. + /* intel1 our optimization controllers */
  13487. + /* Optimize usage of registers for memory addresses */
  13488. + extern int flag_opt_reg_use;
  13489. + /* Do reduce all the mem address givs */
  13490. + extern int flag_all_mem_givs;
  13491. + /* Try to treat index terms of addresses as reducible mem givs */
  13492. + extern int flag_reduce_index_givs;
  13493. + /* After reload try to replace spill slots with equivalent registers */
  13494. + extern int flag_peep_spills;
  13495. + /* After reload try to optimize usage of spill slots in loops */
  13496. + extern int flag_loop_after_global;
  13497. + /* In optimization of loops treats jumps backwards as not nullifying
  13498. +    optimization opportunities.  */
  13499. +    
  13500. + extern int flag_jump_back;
  13501. + /* Do loop copy propogation */
  13502. + extern int flag_copy_prop;
  13503. + /* Do compare elimination */
  13504. + extern int flag_compare_elim;
  13505. + /* Do a mini software pipelining on stack registers */
  13506. + extern int flag_sftwr_pipe;
  13507. + /* Try aggressive changing of jumps taken to jumps not taken */
  13508. + extern int flag_opt_jumps_out;
  13509. + /* Try to replace memory operands with equivalent registers in first
  13510. +    pass of loop optimize */
  13511. +    
  13512. + extern int flag_replace_mem;
  13513. + /* Try to replace memory operands with equivalent stack registers in first
  13514. +    pass of loop optimize */
  13515. +    
  13516. + extern int flag_replace_stack_mem;
  13517. + /* After reload if a register is marked dead at a copy into another
  13518. +    register - see if the other register can be used in the first place.
  13519. +    Thereby eleiminating the copy.  */
  13520. +    
  13521. + extern int flag_reg_reg_copy_opt;
  13522. + /* Move stack registers that will be compared for equality off, the
  13523. +    stack before the comparison.  */
  13524. +    
  13525. + extern int flag_do_offload;
  13526. + /* Optimize usage of stack registers from the stack */
  13527. + extern int flag_opt_reg_stack;
  13528. + /* cse is sometimes detrimental - see flow.c */
  13529. + extern int flag_correct_cse_mistakes;
  13530. + /* Try to push loads back into loops if the loaded register has been spilled */
  13531. + extern int flag_push_load_into_loop;
  13532. + /* After reload use available registers to load memory operands into
  13533. +   them and use the register instead of the memory operand.  */
  13534. +   
  13535. + extern int flag_risc;
  13536. + /* After reload use available registers to load CONST_INTs into
  13537. +   them and then store the register instead of the CONST_INT.  */
  13538. +   
  13539. + extern int flag_risc_const;
  13540. + /* Allow scheduler to try to swap two instructions when the
  13541. +    first increments a register by a constant and the second
  13542. +    uses that register as a base
  13543. + */
  13544. + extern int flag_swap_for_agi;
  13545. + /* A destination that was riscified should stay that way.  */
  13546. + extern int flag_risc_mem_dest;
  13547. + /* Try to use available registers so that a memory operand that is
  13548. +    reloaded will be reloaded into the same register.  This helps
  13549. +    loop_after_global.  */
  13550. +    
  13551. + extern int flag_replace_reload_regs;
  13552. + /* If the riscified instruction has not changed it's place in
  13553. +   scheduling then recombine it into a cisc instruction.  */
  13554. +   
  13555. + extern int flag_recombine;
  13556. + /* These negative flags needed to override optimization
  13557. +    levels which turn them on by default */
  13558. +    
  13559. + extern int flag_no_omit_frame_pointer;
  13560. + extern int flag_no_risc;
  13561. + extern int flag_no_risc_const;
  13562. + extern int flag_no_risc_mem_dest;
  13563. + extern int flag_no_recombine;
  13564. + /* Use the first pass of the scheduler to rearrange between
  13565. +    insns that reference stack registers.  */
  13566. +    
  13567. + extern int flag_schedule_stack_reg_insns;
  13568. + /* Use the first pass of the scheduler to rearrange between
  13569. +    insns that reference stack registers and those that don't
  13570. +    but not amongst themselves  */
  13571. +    
  13572. + extern int flag_interleave_stack_non_stack;
  13573. + /* These negative flags needed to override optimization
  13574. +    levels which turn them on by default */
  13575. +    
  13576. + extern int flag_no_schedule_stack_reg_insns;
  13577. + extern int flag_no_interleave_stack_non_stack;
  13578. + extern int flag_sign_extension_elim;
  13579. + /* Try to lift memory disambiguated memory operands that are stored
  13580. +    to in a loop into a register for the duration of the loop.  */
  13581. +    
  13582. + extern int flag_lift_stores;
  13583. + /* As above but do the disambiguation at runtime. i.e. there
  13584. +    will be two copies of the loop, one disambiguated one not,
  13585. +    And the decision of which one to run will be made at runtime.  */
  13586. +    
  13587. + extern int flag_runtime_lift_stores;
  13588. diff -rNci gcc-2.7.2/flow.c gcc-2.7.2p/flow.c
  13589. *** gcc-2.7.2/flow.c    Mon Aug 28 10:23:34 1995
  13590. --- gcc-2.7.2p/flow.c    Tue Jan 23 09:35:24 1996
  13591. ***************
  13592. *** 286,299 ****
  13593.   static HARD_REG_SET elim_reg_set;
  13594.   
  13595.   /* Forward declarations */
  13596. ! static void find_basic_blocks        PROTO((rtx, rtx));
  13597.   static int uses_reg_or_mem        PROTO((rtx));
  13598.   static void mark_label_ref        PROTO((rtx, rtx, int));
  13599. ! static void life_analysis        PROTO((rtx, int));
  13600.   void allocate_for_life_analysis        PROTO((void));
  13601. ! static void init_regset_vector        PROTO((regset *, regset, int, int));
  13602.   static void propagate_block        PROTO((regset, rtx, rtx, int, 
  13603. !                            regset, int));
  13604.   static rtx flow_delete_insn        PROTO((rtx));
  13605.   static int insn_dead_p            PROTO((rtx, regset, int));
  13606.   static int libcall_dead_p        PROTO((rtx, regset, rtx, rtx));
  13607. --- 286,299 ----
  13608.   static HARD_REG_SET elim_reg_set;
  13609.   
  13610.   /* Forward declarations */
  13611. ! static void find_basic_blocks        PROTO((rtx, rtx, int));
  13612.   static int uses_reg_or_mem        PROTO((rtx));
  13613.   static void mark_label_ref        PROTO((rtx, rtx, int));
  13614. ! static void life_analysis        PROTO((rtx, int, int));
  13615.   void allocate_for_life_analysis        PROTO((void));
  13616. ! /* intel2 static */ void init_regset_vector        PROTO((regset *, regset, int, int));
  13617.   static void propagate_block        PROTO((regset, rtx, rtx, int, 
  13618. !                            regset, int, int));
  13619.   static rtx flow_delete_insn        PROTO((rtx));
  13620.   static int insn_dead_p            PROTO((rtx, regset, int));
  13621.   static int libcall_dead_p        PROTO((rtx, regset, rtx, rtx));
  13622. ***************
  13623. *** 307,322 ****
  13624. --- 307,333 ----
  13625.   static int try_pre_increment        PROTO((rtx, rtx, HOST_WIDE_INT));
  13626.   static rtx find_use_as_address        PROTO((rtx, rtx, HOST_WIDE_INT));
  13627.   void dump_flow_info            PROTO((FILE *));
  13628. + /* intel1 */
  13629. + static void correct_cse_mistakes ();
  13630. + static void count_reg_uses ();
  13631. + static void do_correction ();
  13632.   
  13633.   /* Find basic blocks of the current function and perform data flow analysis.
  13634.      F is the first insn of the function and NREGS the number of register numbers
  13635.      in use.  */
  13636.   
  13637.   void
  13638. + /*
  13639.   flow_analysis (f, nregs, file)
  13640. + */
  13641. + /* intel2 - added the change_f flag to disable changes to the insns, when called
  13642. +  * by memory_simplify. Don't apply any change to an insn if this flag == 0
  13643. +  */
  13644. + flow_analysis (f, nregs, file, change_f)
  13645.        rtx f;
  13646.        int nregs;
  13647.        FILE *file;
  13648. +      int change_f; /* intel2 */
  13649.   {
  13650.     register rtx insn;
  13651.     register int i;
  13652. ***************
  13653. *** 326,331 ****
  13654. --- 337,350 ----
  13655.     static struct {int from, to; } eliminables[] = ELIMINABLE_REGS;
  13656.   #endif
  13657.   
  13658. +   /* intel1 */
  13659. + #ifdef SPARE_REGS
  13660. +   if (change_f && flag_opt_reg_stack)
  13661. +     {
  13662. +       nregs += SPARE_REGS;
  13663. +     }
  13664. + #endif
  13665.     /* Record which registers will be eliminated.  We use this in
  13666.        mark_used_regs. */
  13667.   
  13668. ***************
  13669. *** 372,380 ****
  13670.     /* Allocate some tables that last till end of compiling this function
  13671.        and some needed only in find_basic_blocks and life_analysis.  */
  13672.   
  13673. !   n_basic_blocks = i;
  13674. !   basic_block_head = (rtx *) oballoc (n_basic_blocks * sizeof (rtx));
  13675. !   basic_block_end = (rtx *) oballoc (n_basic_blocks * sizeof (rtx));
  13676.     basic_block_drops_in = (char *) alloca (n_basic_blocks);
  13677.     basic_block_loop_depth = (short *) alloca (n_basic_blocks * sizeof (short));
  13678.     uid_block_number
  13679. --- 391,403 ----
  13680.     /* Allocate some tables that last till end of compiling this function
  13681.        and some needed only in find_basic_blocks and life_analysis.  */
  13682.   
  13683. !   if (change_f || (n_basic_blocks!=i)) 
  13684. !   /* intel2 if change_f is 0 we may have already allocated basic blocks */
  13685. !     {
  13686. !       n_basic_blocks = i;
  13687. !       basic_block_head = (rtx *) oballoc (n_basic_blocks * sizeof (rtx));
  13688. !       basic_block_end = (rtx *) oballoc (n_basic_blocks * sizeof (rtx));
  13689. !     }
  13690.     basic_block_drops_in = (char *) alloca (n_basic_blocks);
  13691.     basic_block_loop_depth = (short *) alloca (n_basic_blocks * sizeof (short));
  13692.     uid_block_number
  13693. ***************
  13694. *** 382,392 ****
  13695.     uid_volatile = (char *) alloca (max_uid_for_flow + 1);
  13696.     bzero (uid_volatile, max_uid_for_flow + 1);
  13697.   
  13698. !   find_basic_blocks (f, nonlocal_label_list);
  13699. !   life_analysis (f, nregs);
  13700.     if (file)
  13701.       dump_flow_info (file);
  13702.   
  13703.     basic_block_drops_in = 0;
  13704.     uid_block_number = 0;
  13705.     basic_block_loop_depth = 0;
  13706. --- 405,420 ----
  13707.     uid_volatile = (char *) alloca (max_uid_for_flow + 1);
  13708.     bzero (uid_volatile, max_uid_for_flow + 1);
  13709.   
  13710. !   find_basic_blocks (f, nonlocal_label_list /* intel2: */, change_f);
  13711. !   life_analysis (f, nregs /* intel2: */, change_f);
  13712.     if (file)
  13713.       dump_flow_info (file);
  13714.   
  13715. +   /* intel1 */
  13716. +   if (flag_correct_cse_mistakes && change_f)
  13717. +     {
  13718. +       correct_cse_mistakes (f, nregs, file);
  13719. +     }
  13720.     basic_block_drops_in = 0;
  13721.     uid_block_number = 0;
  13722.     basic_block_loop_depth = 0;
  13723. ***************
  13724. *** 400,407 ****
  13725.      NONLOCAL_LABEL_LIST is the same local variable from flow_analysis.  */
  13726.   
  13727.   static void
  13728. ! find_basic_blocks (f, nonlocal_label_list)
  13729.        rtx f, nonlocal_label_list;
  13730.   {
  13731.     register rtx insn;
  13732.     register int i;
  13733. --- 428,436 ----
  13734.      NONLOCAL_LABEL_LIST is the same local variable from flow_analysis.  */
  13735.   
  13736.   static void
  13737. ! find_basic_blocks (f, nonlocal_label_list /* intel2: */, change_f)
  13738.        rtx f, nonlocal_label_list;
  13739. +      int change_f;/* intel2 */
  13740.   {
  13741.     register rtx insn;
  13742.     register int i;
  13743. ***************
  13744. *** 634,642 ****
  13745.        They can occur because jump_optimize does not recognize
  13746.        unreachable loops as unreachable.  */
  13747.   
  13748. !       deleted = 0;
  13749.         for (i = 0; i < n_basic_blocks; i++)
  13750. !     if (!block_live[i])
  13751.         {
  13752.           deleted++;
  13753.   
  13754. --- 663,671 ----
  13755.        They can occur because jump_optimize does not recognize
  13756.        unreachable loops as unreachable.  */
  13757.   
  13758. !       deleted=0;
  13759.         for (i = 0; i < n_basic_blocks; i++)
  13760. !     if (!block_live[i] /* intel2: */ && change_f)
  13761.         {
  13762.           deleted++;
  13763.   
  13764. ***************
  13765. *** 874,882 ****
  13766.      regset_size and regset_bytes are also set here.  */
  13767.   
  13768.   static void
  13769. ! life_analysis (f, nregs)
  13770.        rtx f;
  13771.        int nregs;
  13772.   {
  13773.     register regset tem;
  13774.     int first_pass;
  13775. --- 903,912 ----
  13776.      regset_size and regset_bytes are also set here.  */
  13777.   
  13778.   static void
  13779. ! life_analysis (f, nregs /* intel2: */, change_f)
  13780.        rtx f;
  13781.        int nregs;
  13782. +      int change_f;    /* intel2 */
  13783.   {
  13784.     register regset tem;
  13785.     int first_pass;
  13786. ***************
  13787. *** 904,911 ****
  13788.   
  13789.     max_regno = nregs;
  13790.   
  13791. -   bzero (regs_ever_live, sizeof regs_ever_live);
  13792.   
  13793.     /* Allocate and zero out many data structures
  13794.        that will record the data from lifetime analysis.  */
  13795.   
  13796. --- 934,947 ----
  13797.   
  13798.     max_regno = nregs;
  13799.   
  13800.   
  13801. +   /* intel2 - begin */
  13802. +   /* Dont reset the regs_ever_live array if called from memory_simplify */
  13803. +   if (change_f)
  13804. +     {
  13805. +       /* intel2 - end */
  13806. +       bzero (regs_ever_live, sizeof regs_ever_live);
  13807. +     }
  13808.     /* Allocate and zero out many data structures
  13809.        that will record the data from lifetime analysis.  */
  13810.   
  13811. ***************
  13812. *** 950,959 ****
  13813.     for (insn = f; insn; insn = NEXT_INSN (insn))
  13814.       {
  13815.         enum rtx_code code1 = GET_CODE (insn);
  13816. !       if (code1 == CALL_INSN)
  13817.       INSN_VOLATILE (insn) = 1;
  13818.         else if (code1 == INSN || code1 == JUMP_INSN)
  13819.       {
  13820.         /* Delete (in effect) any obvious no-op moves.  */
  13821.         if (GET_CODE (PATTERN (insn)) == SET
  13822.             && GET_CODE (SET_DEST (PATTERN (insn))) == REG
  13823. --- 986,1017 ----
  13824.     for (insn = f; insn; insn = NEXT_INSN (insn))
  13825.       {
  13826.         enum rtx_code code1 = GET_CODE (insn);
  13827. !       if (code1 == CALL_INSN /* intel2: */ && change_f)
  13828.       INSN_VOLATILE (insn) = 1;
  13829.         else if (code1 == INSN || code1 == JUMP_INSN)
  13830.       {
  13831. +         /* intel2 - begin */
  13832. +         /* if change_f is reset, i.e. we are called from memory_simplify, and
  13833. +          * therefore we would like to update the insn's REG_DEAD notes.
  13834. +          * If we find a REG_DEAD note, we remove it here.
  13835. +          */
  13836. +         if (!change_f)
  13837. +         {
  13838. +             register rtx note;
  13839. +             
  13840. +             for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
  13841. +                 if (REG_NOTE_KIND (note) == REG_DEAD
  13842. +                     || REG_NOTE_KIND (note) == REG_UNUSED)
  13843. +                     remove_note(insn, note);
  13844. +         } 
  13845. +         /* intel2 - end */
  13846. + /* intel2 - begin */
  13847. +         if (change_f)
  13848. +         {
  13849. + /* intel2 - end */
  13850.         /* Delete (in effect) any obvious no-op moves.  */
  13851.         if (GET_CODE (PATTERN (insn)) == SET
  13852.             && GET_CODE (SET_DEST (PATTERN (insn))) == REG
  13853. ***************
  13854. *** 1014,1019 ****
  13855. --- 1072,1080 ----
  13856.   #endif
  13857.              && XEXP (SET_SRC (PATTERN (insn)), 0) == stack_pointer_rtx)
  13858.           INSN_VOLATILE (insn) = 1;
  13859. +         /* intel2 - begin */
  13860. +         } /* if (change_f) */
  13861. +         /* intel2 - end */
  13862.       }
  13863.       }
  13864.   
  13865. ***************
  13866. *** 1154,1160 ****
  13867.                      basic_block_head[i], basic_block_end[i], 0,
  13868.                      first_pass ? basic_block_significant[i]
  13869.                      : (regset) 0,
  13870. !                    i);
  13871.           }
  13872.   
  13873.         {
  13874. --- 1215,1221 ----
  13875.                      basic_block_head[i], basic_block_end[i], 0,
  13876.                      first_pass ? basic_block_significant[i]
  13877.                      : (regset) 0,
  13878. !                    i/* intel2: */, change_f);
  13879.           }
  13880.   
  13881.         {
  13882. ***************
  13883. *** 1219,1225 ****
  13884.       {
  13885.         propagate_block (basic_block_live_at_end[i],
  13886.                  basic_block_head[i], basic_block_end[i], 1,
  13887. !                (regset) 0, i);
  13888.   #ifdef USE_C_ALLOCA
  13889.         alloca (0);
  13890.   #endif
  13891. --- 1280,1286 ----
  13892.       {
  13893.         propagate_block (basic_block_live_at_end[i],
  13894.                  basic_block_head[i], basic_block_end[i], 1,
  13895. !                (regset) 0, i/* intel2: */, change_f);
  13896.   #ifdef USE_C_ALLOCA
  13897.         alloca (0);
  13898.   #endif
  13899. ***************
  13900. *** 1316,1322 ****
  13901.      SPACE is of type regset, but it is really as long as NELTS regsets.
  13902.      BYTES_PER_ELT is the number of bytes in one regset.  */
  13903.   
  13904. ! static void
  13905.   init_regset_vector (vector, space, nelts, bytes_per_elt)
  13906.        regset *vector;
  13907.        regset space;
  13908. --- 1377,1383 ----
  13909.      SPACE is of type regset, but it is really as long as NELTS regsets.
  13910.      BYTES_PER_ELT is the number of bytes in one regset.  */
  13911.   
  13912. ! /* intel2 static */ void
  13913.   init_regset_vector (vector, space, nelts, bytes_per_elt)
  13914.        regset *vector;
  13915.        regset space;
  13916. ***************
  13917. *** 1353,1365 ****
  13918.      BNUM is the number of the basic block.  */
  13919.   
  13920.   static void
  13921. ! propagate_block (old, first, last, final, significant, bnum)
  13922.        register regset old;
  13923.        rtx first;
  13924.        rtx last;
  13925.        int final;
  13926.        regset significant;
  13927. !      int bnum;
  13928.   {
  13929.     register rtx insn;
  13930.     rtx prev;
  13931. --- 1414,1426 ----
  13932.      BNUM is the number of the basic block.  */
  13933.   
  13934.   static void
  13935. ! propagate_block (old, first, last, final, significant, bnum /* intel2: */, change_f)
  13936.        register regset old;
  13937.        rtx first;
  13938.        rtx last;
  13939.        int final;
  13940.        regset significant;
  13941. !      int bnum /* intel2: */, change_f;
  13942.   {
  13943.     register rtx insn;
  13944.     rtx prev;
  13945. ***************
  13946. *** 1403,1409 ****
  13947.       loop_depth--;
  13948.       }
  13949.   
  13950. !   if (final)
  13951.       {
  13952.         register int i, offset;
  13953.         REGSET_ELT_TYPE bit;
  13954. --- 1464,1470 ----
  13955.       loop_depth--;
  13956.       }
  13957.   
  13958. !   if (final /* intel2: */ && change_f)
  13959.       {
  13960.         register int i, offset;
  13961.         REGSET_ELT_TYPE bit;
  13962. ***************
  13963. *** 1487,1493 ****
  13964.            "delete" it by turning it into a NOTE of type NOTE_INSN_DELETED.
  13965.            We could really delete it with delete_insn, but that
  13966.            can cause trouble for first or last insn in a basic block.  */
  13967. !       if (final && insn_is_dead)
  13968.           {
  13969.             PUT_CODE (insn, NOTE);
  13970.             NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
  13971. --- 1548,1554 ----
  13972.            "delete" it by turning it into a NOTE of type NOTE_INSN_DELETED.
  13973.            We could really delete it with delete_insn, but that
  13974.            can cause trouble for first or last insn in a basic block.  */
  13975. !       if (final /* intel2: */ && change_f && insn_is_dead)
  13976.           {
  13977.             PUT_CODE (insn, NOTE);
  13978.             NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
  13979. ***************
  13980. *** 1529,1535 ****
  13981.         {
  13982.           register rtx x = PATTERN (insn);
  13983.           /* Does this instruction increment or decrement a register?  */
  13984. !         if (final && GET_CODE (x) == SET
  13985.           && GET_CODE (SET_DEST (x)) == REG
  13986.           && (GET_CODE (SET_SRC (x)) == PLUS
  13987.               || GET_CODE (SET_SRC (x)) == MINUS)
  13988. --- 1590,1596 ----
  13989.         {
  13990.           register rtx x = PATTERN (insn);
  13991.           /* Does this instruction increment or decrement a register?  */
  13992. !         if (final /* intel2: */ && change_f && GET_CODE (x) == SET
  13993.           && GET_CODE (SET_DEST (x)) == REG
  13994.           && (GET_CODE (SET_SRC (x)) == PLUS
  13995.               || GET_CODE (SET_SRC (x)) == MINUS)
  13996. ***************
  13997. *** 1573,1579 ****
  13998.            live.  */
  13999.   
  14000.             mark_set_regs (old, dead, PATTERN (insn),
  14001. !                  final ? insn : NULL_RTX, significant);
  14002.   
  14003.             /* If an insn doesn't use CC0, it becomes dead since we 
  14004.            assume that every insn clobbers it.  So show it dead here;
  14005. --- 1634,1640 ----
  14006.            live.  */
  14007.   
  14008.             mark_set_regs (old, dead, PATTERN (insn),
  14009. !                  (final /* intel2: */ && change_f) ? insn : NULL_RTX, significant);
  14010.   
  14011.             /* If an insn doesn't use CC0, it becomes dead since we 
  14012.            assume that every insn clobbers it.  So show it dead here;
  14013. ***************
  14014. *** 1637,1643 ****
  14015.             old[i] |= live[i];
  14016.           }
  14017.   
  14018. !           if (GET_CODE (insn) == CALL_INSN && final)
  14019.           {
  14020.             /* Any regs live at the time of a call instruction
  14021.                must not go in a register clobbered by calls.
  14022. --- 1698,1704 ----
  14023.             old[i] |= live[i];
  14024.           }
  14025.   
  14026. !           if (GET_CODE (insn) == CALL_INSN && final /* intel2: */ && change_f)
  14027.           {
  14028.             /* Any regs live at the time of a call instruction
  14029.                must not go in a register clobbered by calls.
  14030. ***************
  14031. *** 1655,1661 ****
  14032.            into MAXLIVE and REGS_SOMETIMES_LIVE.
  14033.            Also update counts of how many insns each reg is live at.  */
  14034.   
  14035. !       if (final)
  14036.           {
  14037.             for (i = 0; i < regset_size; i++)
  14038.           {
  14039. --- 1716,1722 ----
  14040.            into MAXLIVE and REGS_SOMETIMES_LIVE.
  14041.            Also update counts of how many insns each reg is live at.  */
  14042.   
  14043. !       if (final /* intel2: */ && change_f)
  14044.           {
  14045.             for (i = 0; i < regset_size; i++)
  14046.           {
  14047. ***************
  14048. *** 2878,2883 ****
  14049. --- 2939,2949 ----
  14050.   {
  14051.     register int i;
  14052.     static char *reg_class_names[] = REG_CLASS_NAMES;
  14053. +   /* intel1 */
  14054. + #ifdef SPARE_REGS
  14055. +   int max_regno;
  14056. +   max_regno = max_reg_num();
  14057. + #endif
  14058.   
  14059.     fprintf (file, "%d registers.\n", max_regno);
  14060.   
  14061. ***************
  14062. *** 2954,2956 ****
  14063. --- 3020,3613 ----
  14064.       }
  14065.     fprintf (file, "\n");
  14066.   }
  14067. + /* intel1 */
  14068. + /* Information about registers */
  14069. + struct regopt_info
  14070. + {
  14071. +   rtx insn_set;            /* If non NULL then the insn that loads the register
  14072. +                           with it's current value */
  14073. +   int num_uses_copied;        /* To count if the reg setter has been copied to
  14074. +                           each of the uses */
  14075. +   char copied_for_src;          /* Set per insn if the insn_set has been copied
  14076. +                           as a result of analysis on the src */
  14077. + };
  14078. + static struct regopt_info *rinfo;
  14079. + /* Count the number of new sets of the register */
  14080. + static int *my_reg_n_sets;
  14081. + /* Count the number of times a register is used in an insn */
  14082. + static int *regs_in_body;
  14083. + /* Count the number of times a register is used in a function */
  14084. + static int *reg_n_uses;
  14085. + /* Copied from sched.c
  14086. +    Return the INSN_LIST containing INSN in LIST, or NULL
  14087. +    if LIST does not contain INSN.  */
  14088. + #ifndef __GNUC__
  14089. + #define __inline
  14090. + #endif
  14091. + __inline static rtx
  14092. + find_insn_list (insn, list)
  14093. +      rtx insn;
  14094. +      rtx list;
  14095. + {
  14096. +   while (list)
  14097. +     {
  14098. +       if (XEXP (list, 0) == insn)
  14099. +     return list;
  14100. +       list = XEXP (list, 1);
  14101. +     }
  14102. +   return 0;
  14103. + }
  14104. + /*
  14105. +   Sometimes cse is done where it is detremental. Consider register 23
  14106. +   in the following insn stream:
  14107. + (insn 18 65 82 (set (reg/v:SI 23)
  14108. +         (plus:SI (reg/v:SI 22)
  14109. +             (const_int -4501))) 32 {movsi+1} (nil)
  14110. +     (nil))
  14111. + (insn 82 18 83 (set (cc0)
  14112. +         (compare:CC (reg/v:SI 22)
  14113. +             (const_int 4500))) 6 {cmpsi_cc} (nil)
  14114. +     (nil))
  14115. + (jump_insn 83 82 90 (set (pc)
  14116. +         (if_then_else (gt (cc0)
  14117. +                 (const_int 0))
  14118. +             (label_ref 63)
  14119. +             (pc))) 185 {bgt+1} (nil)
  14120. +     (nil))
  14121. + (note 90 83 91 "" NOTE_INSN_DELETED)
  14122. + (insn 91 90 93 (set (reg:SI 32)
  14123. +         (ashift:SI (reg/v:SI 23)
  14124. +             (const_int 2))) 136 {ashlsi3} (nil)
  14125. +     (expr_list:REG_DEAD (reg/v:SI 23)
  14126. +         (nil)))
  14127. +   reg 23 appears in insn 91 as a result of cse, before cse insn 90
  14128. +   and 91 were:
  14129. + (insn 90 83 91 (set (reg:SI 33)
  14130. +         (plus:SI (reg/v:SI 22)
  14131. +             (const_int -4501))) -1 (nil)
  14132. +     (nil))
  14133. + (insn 91 90 93 (set (reg:SI 34)
  14134. +         (ashift:SI (reg:SI 33)
  14135. +             (const_int 2))) -1 (nil)
  14136. +     (nil))
  14137. +   since reg 23 does not appear anywhere else in the rtl and it is dead
  14138. +   at insn 91 it would be better to move insn 18 to after insn 90, thus
  14139. +   allowing the combiner to combine insn 18 into 91.
  14140. + */
  14141. + static void
  14142. + correct_cse_mistakes (f, cur_max_reg, dump_file)
  14143. +      rtx f;
  14144. +      int cur_max_reg;
  14145. +      FILE *dump_file;
  14146. + {
  14147. +   rtx insn, src, dest, insn_set, note;
  14148. +   struct regs_mentioned *header, *a_reg_used;
  14149. +   int num_regs, recog_ok, i, regno;
  14150. +   char *storage1, *storage2;
  14151. +   rinfo =
  14152. +     (struct regopt_info *) alloca ((cur_max_reg) * sizeof (struct regopt_info));
  14153. +   bzero (rinfo, (cur_max_reg) * sizeof (struct regopt_info));
  14154. +   reg_n_uses = (int *) alloca ((cur_max_reg) * sizeof (int));
  14155. +   bzero (reg_n_uses, (cur_max_reg) * sizeof (int));
  14156. +   regs_in_body = (int *) alloca ((cur_max_reg) * sizeof (int));
  14157. +   bzero (regs_in_body, (cur_max_reg) * sizeof (int));
  14158. +   my_reg_n_sets = (int *) alloca ((cur_max_reg) * sizeof (int));
  14159. +   bzero (my_reg_n_sets, (cur_max_reg) * sizeof (int));
  14160. +   if (dump_file)
  14161. +     fprintf (dump_file, "\ndoing correct_cse_mistakes:\n\n");
  14162. +   insn = f;
  14163. +   while (insn)
  14164. +     {
  14165. +       if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
  14166. +       || GET_CODE (insn) == CALL_INSN)
  14167. +     {
  14168. +       count_reg_uses (PATTERN (insn), reg_n_uses);
  14169. +     }
  14170. +       insn = NEXT_INSN (insn);
  14171. +     }
  14172. +   insn = f;
  14173. +   while (insn)
  14174. +     {
  14175. +       switch (GET_CODE (insn))
  14176. +     {
  14177. +     case CALL_INSN:
  14178. +       /* Don't want to change reg_n_calls_crosses */
  14179. +       bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
  14180. +       break;
  14181. +     case CODE_LABEL:
  14182. +     case BARRIER:
  14183. +       /* forget everything */
  14184. +       bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
  14185. +       break;
  14186. +     case INSN:
  14187. +           if (GET_CODE (PATTERN (insn)) == CLOBBER)
  14188. +             {
  14189. +           if (GET_CODE (SET_DEST (PATTERN (insn))) == REG)
  14190. +         {
  14191. +           rinfo[ REGNO (SET_DEST (PATTERN (insn)))].insn_set = NULL;
  14192. +           for (i = 0; i < cur_max_reg; i++)
  14193. +             {
  14194. +               if (rinfo[i].insn_set
  14195. +               && reg_overlap_mentioned_p (SET_DEST (PATTERN (insn)), 
  14196. +                     SET_SRC (PATTERN (rinfo[i].insn_set)))
  14197. +             )
  14198. +             {    /* current value of reg dest overwritten */
  14199. +               rinfo[i].insn_set = NULL;
  14200. +             }
  14201. +             }
  14202. +         }
  14203. +             }
  14204. +       else if (GET_CODE (PATTERN (insn)) == PARALLEL)
  14205. +         {
  14206. +           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
  14207. +         {
  14208. +           rtx cur_rtx;
  14209. +           cur_rtx = XVECEXP (PATTERN (insn), 0, i);
  14210. +           if ((GET_CODE (cur_rtx) == SET  
  14211. +                || GET_CODE (cur_rtx) == CLOBBER)
  14212. +               && GET_CODE (SET_DEST (cur_rtx)) == REG)
  14213. +             {
  14214. +               rinfo[ REGNO (SET_DEST (cur_rtx))].insn_set = NULL;
  14215. +               for (i = 0; i < cur_max_reg; i++)
  14216. +                 {
  14217. +                   if (rinfo[i].insn_set
  14218. +                   && reg_overlap_mentioned_p (SET_DEST (cur_rtx), 
  14219. +                          SET_SRC (PATTERN (rinfo[i].insn_set)))
  14220. +                 )
  14221. +                 {    /* current value of reg dest overwritten */
  14222. +                   rinfo[i].insn_set = NULL;
  14223. +                 }
  14224. +                 }
  14225. +             }
  14226. +           if (!(GET_CODE (cur_rtx) == SET  
  14227. +                || GET_CODE (cur_rtx) == CLOBBER
  14228. +                || GET_CODE (cur_rtx) == USE))
  14229. +                 bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
  14230. +         }
  14231. +         }
  14232. +       else if (GET_CODE (PATTERN (insn)) == SET)
  14233. +         {
  14234. +           dest = SET_DEST (PATTERN (insn));
  14235. +           src = SET_SRC (PATTERN (insn));
  14236. +           if (GET_CODE (src) == REG)
  14237. +         {
  14238. +           i = REGNO (src);
  14239. +                   if (rinfo[i].insn_set
  14240. +                       && BLOCK_NUM (insn) == BLOCK_NUM (rinfo[i].insn_set))
  14241. +                     { /* Since insn_set cannot be deleted stop optimization */
  14242. +                       rinfo[i].insn_set = NULL;
  14243. +                     }
  14244. +                 }
  14245. +           else /* (GET_CODE (src) != REG) */
  14246. +         {
  14247. +               count_reg_uses (src, regs_in_body);
  14248. +           for (i = 0; i < cur_max_reg; i++)
  14249. +             {
  14250. +                       if (rinfo[i].insn_set
  14251. +                           && regs_in_body[i]
  14252. +                           && BLOCK_NUM (insn) == BLOCK_NUM (rinfo[i].insn_set))
  14253. +                         { /* Since insn_set cannot be deleted stop optimization */
  14254. +                           rinfo[i].insn_set = NULL;
  14255. +                         }
  14256. +               if (reg_n_sets[i] == 1
  14257. +                   && regs_in_body[i]
  14258. +               && rinfo[i].insn_set
  14259. +               && GET_CODE (rinfo[i].insn_set) == INSN)
  14260. +             {    
  14261. +               if (find_regno_note (insn, REG_DEAD, i))
  14262. +                 {
  14263. +                   /* copy insn_set just prior to insn */
  14264. +                   do_correction (i, insn, dump_file);
  14265. +                 }
  14266. +               else
  14267. +                 { /* A use that is not dead - stop.  */
  14268. +                               rinfo[i].insn_set = NULL;
  14269. +                 }
  14270. +             }
  14271. +             }
  14272. +           bzero (regs_in_body, cur_max_reg * sizeof (int));
  14273. +         }
  14274. +           if (GET_CODE (dest) != REG)
  14275. +         {
  14276. +           count_reg_uses (dest, regs_in_body);
  14277. +           for (i = 0; i < cur_max_reg; i++)
  14278. +             {
  14279. +                       if (rinfo[i].insn_set
  14280. +                           && regs_in_body[i]
  14281. +                           && BLOCK_NUM (insn) == BLOCK_NUM (rinfo[i].insn_set))
  14282. +                         { /* Since insn_set cannot be deleted stop optimization */
  14283. +                           rinfo[i].insn_set = NULL;
  14284. +                         }
  14285. +               if (reg_n_sets[i] == 1
  14286. +                   && !rinfo[i].copied_for_src
  14287. +                   && regs_in_body[i]
  14288. +               && rinfo[i].insn_set
  14289. +               && GET_CODE (rinfo[i].insn_set) == INSN)
  14290. +             {
  14291. +               if (find_regno_note (insn, REG_DEAD, i))
  14292. +                 {
  14293. +                   /* copy insn_set just prior to insn */
  14294. +                   do_correction (i, insn, dump_file);
  14295. +                 }
  14296. +               else
  14297. +                 { /* A use that is not dead - stop.  */
  14298. +                               rinfo[i].insn_set = NULL;
  14299. +                 }
  14300. +             }
  14301. +             }
  14302. +           bzero (regs_in_body, cur_max_reg * sizeof (int));
  14303. +         }
  14304. +           for (i = 0; i < cur_max_reg; i++)
  14305. +         {
  14306. +           rinfo[i].copied_for_src = 0;
  14307. +         }
  14308. +           if (GET_CODE (dest) == REG)
  14309. +         {
  14310. +           for (i = 0; i < cur_max_reg; i++)
  14311. +             {
  14312. +               if (rinfo[i].insn_set
  14313. +               && reg_overlap_mentioned_p (dest, SET_SRC (PATTERN (rinfo[i].insn_set)))
  14314. +             )
  14315. +             {    /* current value of reg dest overwritten */
  14316. +               rinfo[i].insn_set = NULL;
  14317. +             }
  14318. +             }
  14319. +           if (reg_overlap_mentioned_p (dest, SET_SRC (PATTERN (insn))))
  14320. +             {
  14321. +               rinfo[REGNO (dest)].insn_set = NULL;
  14322. +             }
  14323. +           else
  14324. +             {
  14325. +               if ((GET_CODE (SET_SRC (PATTERN (insn))) == ASHIFT
  14326. +                    && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG
  14327. +                && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
  14328. +               || (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS
  14329. +                       && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG
  14330. +                   && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == SYMBOL_REF)
  14331. +               || (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS
  14332. +                   && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == MULT
  14333. +                   && GET_CODE (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0)) == REG
  14334. +                   && GET_CODE (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 1)) == CONST_INT
  14335. +                   && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
  14336. +               || (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS
  14337. +                       && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG
  14338. +                   && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
  14339. +             )
  14340. +             {    /* these may be combinable */
  14341. +               if (REG_NOTES (insn) == NULL)
  14342. +                 { /* Don't want to mess around with
  14343. +                      the REG_NOTES.  */
  14344. +                   rinfo[REGNO (dest)].insn_set = insn;
  14345. +                 }
  14346. +             }
  14347. +               else
  14348. +             {
  14349. +               rinfo[REGNO (dest)].insn_set = NULL;
  14350. +             }
  14351. +             }
  14352. +         }
  14353. +         }
  14354. +       else if (GET_CODE (PATTERN (insn)) == USE)
  14355. +         ; /* nothing */
  14356. +       else 
  14357. +         {
  14358. +           bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
  14359. +         }
  14360. +       /* A register that dies cannot be used further in a substitution.  */
  14361. +           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
  14362. +         if (REG_NOTE_KIND (note) == REG_DEAD
  14363. +         && GET_CODE (XEXP (note, 0)) == REG)
  14364. +           {
  14365. +         for (i = 0; i < cur_max_reg; i++)
  14366. +           {
  14367. +             if (rinfo[i].insn_set
  14368. +             && reg_overlap_mentioned_p (XEXP (note, 0), 
  14369. +                   SET_SRC (PATTERN (rinfo[i].insn_set)))
  14370. +                )
  14371. +               {    
  14372. +               rinfo[i].insn_set = NULL;
  14373. +                   }
  14374. +           }    
  14375. +           }
  14376. +       break;
  14377. +     case JUMP_INSN:
  14378. +     case NOTE:
  14379. +       break;
  14380. +     default:
  14381. +       bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
  14382. +       break;
  14383. +     }
  14384. +       insn = NEXT_INSN (insn);
  14385. +     }
  14386. +   for (i = 0; i < cur_max_reg; i++)
  14387. +     reg_n_sets[i] += my_reg_n_sets[i];
  14388. + }
  14389. + /*
  14390. +   Increment the reg_n_uses element for each register mentioned in body
  14391. +   and for each time it is mentioned
  14392. + */
  14393. + static void
  14394. + count_reg_uses (body, where_to_count)
  14395. +      rtx body;
  14396. +      int *where_to_count;
  14397. + {
  14398. +   int i, j, ret_val = 0;
  14399. +   char *fmt;
  14400. +   register RTX_CODE code = GET_CODE (body);
  14401. +   if (code == CLOBBER)
  14402. +     return;
  14403. +   else if (code == REG)
  14404. +     where_to_count[REGNO (body)]++;
  14405. +   else if (code == SET)
  14406. +     {
  14407. +       if (GET_CODE (SET_DEST (body)) != REG)
  14408. +     {
  14409. +       count_reg_uses (SET_DEST (body), where_to_count);
  14410. +     }
  14411. +       count_reg_uses (SET_SRC (body), where_to_count);
  14412. +     }
  14413. +   else
  14414. +     {
  14415. +       fmt = GET_RTX_FORMAT (code);
  14416. +       for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  14417. +     if (fmt[i] == 'e')
  14418. +       count_reg_uses (XEXP (body, i), where_to_count);
  14419. +     else if (fmt[i] == 'E' || fmt[i] == 'V')
  14420. +       {
  14421. +         for (j = 0; j < XVECLEN (body, i); j++)
  14422. +           count_reg_uses (XVECEXP (body, i, j), where_to_count);
  14423. +       }
  14424. +     }
  14425. + }
  14426. + /*
  14427. +    Copy the insn that sets regnum to just before insn.
  14428. +    If that insn has been copied to in front of each of
  14429. +    it's uses then delete it
  14430. + */
  14431. + static void
  14432. + do_correction (regnum, insn, dump_file)
  14433. +      int regnum;
  14434. +      rtx insn;
  14435. +      FILE * dump_file;
  14436. + {
  14437. +   rtx insn_set;
  14438. +   int i;
  14439. +   
  14440. +   insn_set
  14441. +     = rinfo[regnum].insn_set;
  14442. +   if (BLOCK_NUM (insn) == BLOCK_NUM (insn_set))
  14443. +     { /* Since insn_set cannot be deleted stop optimization */
  14444. +       rinfo[regnum].insn_set = NULL;
  14445. +       return;
  14446. +     }
  14447. +   emit_insn_before (
  14448. +              copy_rtx (PATTERN (insn_set)),
  14449. +              insn);
  14450. +    
  14451. +   if (REG_NOTES (insn_set))
  14452. +     {
  14453. +       REG_NOTES (PREV_INSN (insn))
  14454. +     = copy_rtx (REG_NOTES (insn_set));
  14455. +     }
  14456. +   LOG_LINKS (insn)
  14457. +     = gen_rtx (INSN_LIST, VOIDmode, PREV_INSN (insn),
  14458. +            LOG_LINKS (insn));
  14459. +   if (find_insn_list (insn_set,
  14460. +               LOG_LINKS (insn)))
  14461. +     remove_dependence (insn, insn_set);
  14462. +   rinfo[regnum].num_uses_copied += regs_in_body[regnum];
  14463. +   my_reg_n_sets[regnum]++;
  14464. +   if (dump_file)
  14465. +     {
  14466. +       fprintf (dump_file,
  14467. +            " copy insn %d to before insn %d\n",
  14468. +            INSN_UID (insn_set), INSN_UID (insn));
  14469. +     }
  14470. +   if (rinfo[regnum].num_uses_copied == reg_n_uses[regnum])
  14471. +     {    /* insn_set is no longer relevant - delete it */
  14472. +       rinfo[regnum].insn_set = NULL;
  14473. +       PUT_CODE (insn_set, NOTE);
  14474. +       NOTE_LINE_NUMBER (insn_set) = NOTE_INSN_DELETED;
  14475. +       NOTE_SOURCE_FILE (insn_set) = 0;
  14476. +       if (dump_file)
  14477. +     {
  14478. +       fprintf (dump_file,
  14479. +            " delete insn %d \n",
  14480. +            INSN_UID (insn_set));
  14481. +     }
  14482. +       reg_n_sets[regnum]--;
  14483. +     }
  14484. +   /* If insn was a basic block head then now the copy is
  14485. +      the basic block head.  */
  14486. +   for (i = 0; i < n_basic_blocks; i++)
  14487. +     {
  14488. +       if (basic_block_head[i] == insn)
  14489. +         {
  14490. +           basic_block_head[i] = PREV_INSN (insn);
  14491. +           break;
  14492. +         }
  14493. +     }
  14494. +   
  14495. + }
  14496. + /* intel2 */
  14497. + /* Call flow_analysis without changing insns, and if save_pseudo is set, saves
  14498. +    the basic_block_live_at_start information, concerning the pseudo registers,
  14499. +    and restores it after flow_analysis. */
  14500. + void
  14501. + hard_reg_flow_analysis (f, file, save_pseudo)
  14502. +      rtx f;
  14503. +      FILE *file;
  14504. +      int save_pseudo;
  14505. + {
  14506. +   int limit;
  14507. +   register int block, regno;
  14508. +   /* Element N is a regset describing the registers live
  14509. +      at the start of basic block N, as was saved before the call to
  14510. +      flow_analysis. We use it to restore the contents of the pseudo registers,
  14511. +      needed by other phases. */
  14512. +     
  14513. +   regset *basic_block_live_at_start_saved;
  14514. +     
  14515. + #if 0
  14516. +   register int j;
  14517. + #endif
  14518. +   if (save_pseudo)
  14519. +     {
  14520. +       int regset_size = ((max_regno + REGSET_ELT_BITS - 1) / REGSET_ELT_BITS);
  14521. +       int regset_bytes = regset_size * sizeof (*(regset)0);
  14522. +       basic_block_live_at_start_saved =
  14523. +                  (regset *) alloca (n_basic_blocks * sizeof (regset));
  14524. +       /* copy basic_block_live_at_start to basic_block_live_at_start_saved */
  14525. +       for (block = 0; block < n_basic_blocks; block++)
  14526. +         {
  14527. +           basic_block_live_at_start_saved[block] = (regset) alloca (regset_bytes);
  14528. +           bcopy (basic_block_live_at_start[block],
  14529. +                  basic_block_live_at_start_saved[block],
  14530. +                  regset_bytes);
  14531. +         }
  14532. + #if 0
  14533. +       /* Check if copy is o.k. */
  14534. +       if (file)
  14535. +         {
  14536. +           fprintf (file, "Pseudo registers live at start:\n");
  14537. +           for (block = 0; block < n_basic_blocks; block++)
  14538. +         {
  14539. +           fprintf (file, "\nBlock no. %d original:", block);
  14540. +           for (regno = FIRST_PSEUDO_REGISTER; regno < max_regno; regno++)
  14541. +             {
  14542. +               register int offset = regno / REGSET_ELT_BITS;
  14543. +               register REGSET_ELT_TYPE bit
  14544. +                        = (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
  14545. +               if ((basic_block_live_at_start_saved[block][offset] & bit)
  14546. +                   ^ (basic_block_live_at_start[block][offset] & bit))
  14547. +                 {
  14548. +               fprintf (file, "\nERROR: differnt values in regsets!\n");
  14549. +               fprintf (file,
  14550. +                    "original: %d, saved: %d\n",
  14551. +                    basic_block_live_at_start[block][offset],
  14552. +                    basic_block_live_at_start_saved[block][offset]);
  14553. +                   abort ();
  14554. +                 }
  14555. +               if (basic_block_live_at_start[block][offset] & bit)
  14556. +                 fprintf (file, " %d", regno);
  14557. +             }
  14558. +           fprintf (file, "\nSaved:");
  14559. +           for (regno = FIRST_PSEUDO_REGISTER; regno < max_regno; regno++)
  14560. +             {
  14561. +               register int offset = regno / REGSET_ELT_BITS;
  14562. +               register REGSET_ELT_TYPE bit
  14563. +                        = (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
  14564. +               if (basic_block_live_at_start_saved[block][offset] & bit)
  14565. +                 fprintf (file, " %d", regno);
  14566. +             }
  14567. +           fprintf (file, "\n");
  14568. +             }  /* for (block = 0; block < n_basic_blocks; block++) */
  14569. +         }  /* if (file) */
  14570. + #endif
  14571. +     }  /* if (save_pseudo) */
  14572. +   limit = max_reg_num ();
  14573. +   /* Do control and data flow analysis, and write the results to the dump
  14574. +    * file, if dump wanted.
  14575. +    */
  14576. +   flow_analysis (f, limit, file, 0 /* do not allow a change to the insns */ );
  14577. +   if (save_pseudo)
  14578. +     {
  14579. +       /* restore the contents of pseudo registers if basic_block_live_at_start */
  14580. +       for (block = 0; block < n_basic_blocks; block++)
  14581. +         {
  14582. +           for (regno = FIRST_PSEUDO_REGISTER; regno < max_regno; regno++)
  14583. +             {
  14584. +               register int offset = regno / REGSET_ELT_BITS;
  14585. +               register REGSET_ELT_TYPE bit
  14586. +                        = (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
  14587. +           if (basic_block_live_at_start_saved[block][offset] & bit)
  14588. +             basic_block_live_at_start[block][offset] |= bit;
  14589. +           else
  14590. +             basic_block_live_at_start[block][offset] &= ~bit;
  14591. +             }
  14592. +         }
  14593. + #if 0
  14594. +       /* Check if copy is o.k. */
  14595. +       if (file)
  14596. +         {
  14597. +           fprintf (file, "Pseudo registers live at start - restored :\n");
  14598. +           for (block = 0; block < n_basic_blocks; block++)
  14599. +         {
  14600. +           fprintf (file, "Block no. %d:", block);
  14601. +           for (regno = FIRST_PSEUDO_REGISTER; regno < max_regno; regno++)
  14602. +             {
  14603. +               register int offset = regno / REGSET_ELT_BITS;
  14604. +               register REGSET_ELT_TYPE bit
  14605. +                        = (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
  14606. +               if (basic_block_live_at_start[block][offset] & bit)
  14607. +                 fprintf (file, " %d", regno);
  14608. +             }
  14609. +           fprintf (file, "\n");
  14610. +             }
  14611. +         }
  14612. + #endif
  14613. +     }  /* if (save_pseudo) */
  14614. + }  /* hard_reg_flow_analysis (f, file, save_pseudo) */
  14615. diff -rNci gcc-2.7.2/fold-const.c gcc-2.7.2p/fold-const.c
  14616. *** gcc-2.7.2/fold-const.c    Fri Sep 15 22:26:12 1995
  14617. --- gcc-2.7.2p/fold-const.c    Tue Jan 23 09:35:24 1996
  14618. ***************
  14619. *** 3645,3651 ****
  14620.       return fold (build (MINUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
  14621.         else if (! FLOAT_TYPE_P (type))
  14622.       {
  14623. !       if (integer_zerop (arg1))
  14624.           return non_lvalue (convert (type, arg0));
  14625.   
  14626.         /* If we are adding two BIT_AND_EXPR's, both of which are and'ing
  14627. --- 3645,3656 ----
  14628.       return fold (build (MINUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
  14629.         else if (! FLOAT_TYPE_P (type))
  14630.       {
  14631. !       if (integer_zerop (arg1)
  14632. !           /* intel1 if it is pointer_type then removing the + 0 here
  14633. !              will cause references to array[0] not to be marked
  14634. !              as MEM_IN_STRUCT_P.  So just leave the + 0 here - it
  14635. !              will be removed when the tree is made into rtl anyway.  */
  14636. !           && TREE_CODE (TREE_TYPE (arg0)) != POINTER_TYPE)
  14637.           return non_lvalue (convert (type, arg0));
  14638.   
  14639.         /* If we are adding two BIT_AND_EXPR's, both of which are and'ing
  14640. ***************
  14641. *** 4010,4015 ****
  14642. --- 4015,4045 ----
  14643.       case FLOOR_DIV_EXPR:
  14644.       case CEIL_DIV_EXPR:
  14645.       case EXACT_DIV_EXPR:
  14646. +    /* intel1 - implemet x/C where c is floating point and a power of two
  14647. +               as x*(1/C)
  14648. +    */
  14649. + #ifndef REAL_IS_NOT_DOUBLE
  14650. +       if (HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
  14651. +          && TREE_CODE (t) == RDIV_EXPR
  14652. +          && TREE_CODE (TREE_TYPE (t)) == REAL_TYPE
  14653. +          && TYPE_NAME (TREE_TYPE (t))
  14654. +          && TREE_CODE (TYPE_NAME TREE_TYPE (t)) == TYPE_DECL
  14655. +          && TREE_CODE (TREE_OPERAND (t,  1)) == REAL_CST
  14656. +          && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1))) == REAL_TYPE
  14657. +          && TYPE_NAME (TREE_TYPE (TREE_OPERAND (t, 1)))
  14658. +          && TREE_CODE (TYPE_NAME (TREE_TYPE (TREE_OPERAND(t, 1))))== TYPE_DE CL
  14659. +          && TREE_REAL_CST (TREE_OPERAND (t, 1)) >= 2.0
  14660. +          && TREE_REAL_CST (TREE_OPERAND (t, 1))
  14661. +           ==(double)(REAL_VALUE_UNSIGNED_FIX(TREE_REAL_CST(TREE_OPERAND(t, 1))))
  14662. +           &&exact_log2(REAL_VALUE_UNSIGNED_FIX(TREE_REAL_CST(TREE_OPERAND(t,1)))) != -1
  14663. +          )
  14664. +         {
  14665. +           TREE_SET_CODE (t, MULT_EXPR);
  14666. +           code = TREE_CODE (t);
  14667. +           TREE_REAL_CST (TREE_OPERAND (t, 1))
  14668. +             = 1.0 / TREE_REAL_CST (TREE_OPERAND (t, 1));
  14669. +         }
  14670. + #endif
  14671.         if (integer_onep (arg1))
  14672.       return non_lvalue (convert (type, arg0));
  14673.         if (integer_zerop (arg1))
  14674. diff -rNci gcc-2.7.2/jump.c gcc-2.7.2p/jump.c
  14675. *** gcc-2.7.2/jump.c    Thu Oct 26 11:27:39 1995
  14676. --- gcc-2.7.2p/jump.c    Tue Jan 23 09:35:27 1996
  14677. ***************
  14678. *** 1920,1926 ****
  14679.   
  14680.             /* First, cross jumping of conditional jumps:  */
  14681.   
  14682. !           if (cross_jump && condjump_p (insn))
  14683.           {
  14684.             rtx newjpos, newlpos;
  14685.             rtx x = prev_real_insn (JUMP_LABEL (insn));
  14686. --- 1920,1935 ----
  14687.   
  14688.             /* First, cross jumping of conditional jumps:  */
  14689.   
  14690. !           if (cross_jump && condjump_p (insn)
  14691. !           /* intel1 */
  14692. ! #ifdef NO_CROSS_JUMP_ON_LOOP_ENTRY
  14693. !                   && !(GET_CODE (NEXT_INSN(insn)) == NOTE
  14694. !                    && 
  14695. !                    (NOTE_LINE_NUMBER (NEXT_INSN(insn)) == NOTE_INSN_LOOP_BEG 
  14696. !                     || NOTE_LINE_NUMBER (NEXT_INSN(insn)) == NOTE_INSN_LOOP_END)
  14697. !                   )
  14698. ! #endif
  14699. !              )
  14700.           {
  14701.             rtx newjpos, newlpos;
  14702.             rtx x = prev_real_insn (JUMP_LABEL (insn));
  14703. diff -rNci gcc-2.7.2/loop.c gcc-2.7.2p/loop.c
  14704. *** gcc-2.7.2/loop.c    Tue Oct  3 16:17:16 1995
  14705. --- gcc-2.7.2p/loop.c    Tue Jan 23 09:25:29 1996
  14706. ***************
  14707. *** 39,44 ****
  14708. --- 39,45 ----
  14709.   #include "rtl.h"
  14710.   #include "obstack.h"
  14711.   #include "expr.h"
  14712. + #include "basic-block.h" /* intel1 */
  14713.   #include "insn-config.h"
  14714.   #include "insn-flags.h"
  14715.   #include "regs.h"
  14716. ***************
  14717. *** 46,51 ****
  14718. --- 47,53 ----
  14719.   #include "recog.h"
  14720.   #include "flags.h"
  14721.   #include "real.h"
  14722. + #include "reload.h" /* intel1 */
  14723.   #include "loop.h"
  14724.   
  14725.   /* Vector mapping INSN_UIDs to luids.
  14726. ***************
  14727. *** 97,107 ****
  14728.   
  14729.   rtx *loop_number_exit_labels;
  14730.   
  14731. - /* Indexed by loop number, counts the number of LABEL_REFs on
  14732. -    loop_number_exit_labels for this loop and all loops nested inside it.  */
  14733. - int *loop_number_exit_count;
  14734.   /* Holds the number of loop iterations.  It is zero if the number could not be
  14735.      calculated.  Must be unsigned since the number of iterations can
  14736.      be as high as 2^wordsize-1.  For loops with a wider iterator, this number
  14737. --- 99,104 ----
  14738. ***************
  14739. *** 191,196 ****
  14740. --- 188,196 ----
  14741.   
  14742.   static struct obstack temp_obstack;
  14743.   
  14744. + /* intel1 */
  14745. + extern struct obstack momentary_obstack;
  14746.   /* This is where the pointer to the obstack being used for RTL is stored.  */
  14747.   
  14748.   extern struct obstack *rtl_obstack;
  14749. ***************
  14750. *** 286,291 ****
  14751. --- 286,349 ----
  14752.   static int last_use_this_basic_block ();
  14753.   static void record_initial ();
  14754.   static void update_reg_last_use ();
  14755. + /* intel1 */
  14756. + static int compare_elimination ();
  14757. + static attempt_new_rtx ();
  14758. + static rtx make_new_use ();
  14759. + static int possible_compare_elimination ();
  14760. + static void find_regs_mentioned ();
  14761. + static void use_regs_source ();
  14762. + static rtx replace_mems ();
  14763. + static void replace_reg  ();
  14764. + static int two_to_power ();
  14765. + static int jumps_back_in_loop ();
  14766. + static loop_copy_propogate ();
  14767. + static do_replace ();
  14768. + static rtx subst_cands ();
  14769. + static try_unroll_propogation ();
  14770. + static rtx unroll_subst_cands ();
  14771. + static unroll_consistancy_maintained ();
  14772. + static int do_reduce_index ();
  14773. + static loop_spl ();
  14774. + void loop_after_global ();
  14775. + static int spill_invariant_p ();
  14776. + static void move_spills_out ();
  14777. + static void move_spill_movables ();
  14778. + static rtx subst_stack_slot ();
  14779. + static int check_if_jumps_out_of_loop ();
  14780. + static void mark_regs_alive_at_exit ();
  14781. + static void verify_spill_candidates ();
  14782. + static void mark_spill_candidates ();
  14783. + static void spill_handle_regs_mentioned ();
  14784. + static int is_updated_by_const ();
  14785. + static int is_updated_by_const_or_reg ();
  14786. + static void peep_init_info ();
  14787. + static void spill_peep_insn ();
  14788. + void update_stack_offset ();
  14789. + static void replace_spill_slots ();
  14790. + static rtx replace_linked_regs ();
  14791. + static void mark_regs_live_outside ();
  14792. + static void mark_regs_mentioned ();
  14793. + static int loop_contains_loop ();
  14794. + static void push_load_into_loop ();
  14795. + static int spill_slot_unused_between ();
  14796. + static int spill_slot_mentioned ();
  14797. + void init_undo_buf ();
  14798. + void subst_in_insn ();
  14799. + static void inner_subst_in_insn ();
  14800. + void loop_undo_all ();
  14801. + static void update_last_reloads ();
  14802. + static void sign_extension_reduction ();
  14803. + static void validate_all_references ();
  14804. + static void lift_stores ();
  14805. + static void mark_mem_refs ();
  14806. + static void insert_mem_ref ();
  14807. + static void opt_reg_use_copy ();
  14808. + int doing_spl = 0;
  14809. + int doing_loop_after_global = 0;
  14810. + static char * reg_live_outside_loop;
  14811. + static int cur_stack_offset = 0;
  14812.   
  14813.   /* Relative gain of eliminating various kinds of operations.  */
  14814.   int add_cost;
  14815. ***************
  14816. *** 293,298 ****
  14817. --- 351,360 ----
  14818.   int shift_cost;
  14819.   int mult_cost;
  14820.   #endif
  14821. + /* intel1 maximum # of insns in loop for which compare elimination */
  14822. + #ifndef MAX_CMP_ELIM
  14823. + #define MAX_CMP_ELIM 100
  14824. + #endif
  14825.   
  14826.   /* Benefit penalty, if a giv is not replaceable, i.e. must emit an insn to
  14827.      copy the value of the strength reduced giv to its original register.  */
  14828. ***************
  14829. *** 341,346 ****
  14830. --- 403,414 ----
  14831.   
  14832.     max_reg_before_loop = max_reg_num ();
  14833.   
  14834. +   /* intel1 */
  14835. + #ifdef SAVE_ON_REGS
  14836. +   if (!flag_all_mem_givs && flag_opt_reg_use)
  14837. +     reg_live_outside_loop = (char *) alloca(max_reg_before_loop);
  14838. + #endif
  14839.     moved_once = (char *) alloca (max_reg_before_loop);
  14840.     bzero (moved_once, max_reg_before_loop);
  14841.   
  14842. ***************
  14843. *** 358,364 ****
  14844.   
  14845.     /* Don't waste time if no loops.  */
  14846.     if (max_loop_num == 0)
  14847. !     return;
  14848.   
  14849.     /* Get size to use for tables indexed by uids.
  14850.        Leave some space for labels allocated by find_and_verify_loops.  */
  14851. --- 426,442 ----
  14852.   
  14853.     /* Don't waste time if no loops.  */
  14854.     if (max_loop_num == 0)
  14855. !     {
  14856. !       /* intel1 */
  14857. ! #ifdef SAVE_ON_REGS
  14858. !       if (!doing_loop_after_global && flag_opt_reg_use)
  14859. !         {
  14860. !           use_regs_source (f, NULL, 0);
  14861. !           opt_reg_use_copy (f);
  14862. !         }
  14863. ! #endif
  14864. !       return;
  14865. !     }
  14866.   
  14867.     /* Get size to use for tables indexed by uids.
  14868.        Leave some space for labels allocated by find_and_verify_loops.  */
  14869. ***************
  14870. *** 377,383 ****
  14871.     loop_outer_loop = (int *) alloca (max_loop_num * sizeof (int));
  14872.     loop_invalid = (char *) alloca (max_loop_num * sizeof (char));
  14873.     loop_number_exit_labels = (rtx *) alloca (max_loop_num * sizeof (rtx));
  14874. -   loop_number_exit_count = (int *) alloca (max_loop_num * sizeof (int));
  14875.   
  14876.     /* Find and process each loop.
  14877.        First, find them, and record them in order of their beginnings.  */
  14878. --- 455,460 ----
  14879. ***************
  14880. *** 386,392 ****
  14881.     /* Now find all register lifetimes.  This must be done after
  14882.        find_and_verify_loops, because it might reorder the insns in the
  14883.        function.  */
  14884. !   reg_scan (f, max_reg_num (), 1);
  14885.   
  14886.     /* See if we went too far.  */
  14887.     if (get_max_uid () > max_uid_for_loop)
  14888. --- 463,470 ----
  14889.     /* Now find all register lifetimes.  This must be done after
  14890.        find_and_verify_loops, because it might reorder the insns in the
  14891.        function.  */
  14892. !   /* intel1  Last paramater of reg_scan used to be 1.  */
  14893. !   reg_scan (f, max_reg_num (), !doing_loop_after_global);
  14894.   
  14895.     /* See if we went too far.  */
  14896.     if (get_max_uid () > max_uid_for_loop)
  14897. ***************
  14898. *** 437,442 ****
  14899. --- 515,557 ----
  14900.         scan_loop (loop_number_loop_starts[i], loop_number_loop_ends[i],
  14901.            max_reg_num ());
  14902.   
  14903. +   /* intel1 */
  14904. +   if (flag_strength_reduce && flag_copy_prop)
  14905. +     {  
  14906. +       for (i = max_loop_num-1; i >= 0; i--)
  14907. +         {
  14908. +           if (! loop_invalid[i] && loop_number_loop_ends[i])
  14909. +             loop_copy_propogate (loop_number_loop_starts[i], loop_number_loop_ends[i]);
  14910. +         }
  14911. +     }
  14912. +   /* intel1 */
  14913. +   if ((flag_lift_stores || flag_runtime_lift_stores) 
  14914. +       && !doing_loop_after_global)
  14915. +     {  
  14916. +       for (i = max_loop_num-1; i >= 0; i--)
  14917. +         {
  14918. +           if (! loop_invalid[i] && loop_number_loop_ends[i])
  14919. +                lift_stores (loop_number_loop_starts[i], loop_number_loop_ends[i]);
  14920. +         }
  14921. +     }
  14922. + #ifdef SAVE_ON_REGS
  14923. +   if (!doing_loop_after_global && flag_opt_reg_use)
  14924. +     {
  14925. +       use_regs_source (f, NULL, 0); 
  14926. +       opt_reg_use_copy (f);
  14927. +     }
  14928. + #endif
  14929. +   /* intel1 */
  14930. + #ifdef STORE_NOT_SET_CC0
  14931. + #ifdef STACK_REGS
  14932. +   if (flag_sftwr_pipe && !doing_loop_after_global)
  14933. +       for (i = max_loop_num-1; i >= 0; i--)
  14934. +         {
  14935. +           loop_spl (loop_number_loop_starts[i], loop_number_loop_ends[i], i, 0);
  14936. +         }
  14937. + #endif
  14938. + #endif
  14939.     /* If debugging and unrolling loops, we must replicate the tree nodes
  14940.        corresponding to the blocks inside the loop, so that the original one
  14941.        to one mapping will remain.  */
  14942. ***************
  14943. *** 493,501 ****
  14944. --- 608,636 ----
  14945.        if it was used exactly once; contains const0_rtx if it was used more
  14946.        than once.  */
  14947.     rtx *reg_single_usage = 0;
  14948. +   
  14949.     /* Nonzero if we are scanning instructions in a sub-loop.  */
  14950.     int loop_depth = 0;
  14951.   
  14952. +   /* intel1 */
  14953. +   if (doing_loop_after_global
  14954. +      && !(GET_CODE (PREV_INSN (end)) == JUMP_INSN
  14955. +      &&   GET_CODE (NEXT_INSN (loop_start)) == CODE_LABEL
  14956. +      &&   JUMP_LABEL (PREV_INSN (end)) == NEXT_INSN (loop_start)
  14957. +       )
  14958. +     )
  14959. +   {
  14960. +     return;
  14961. +   }
  14962. + #ifdef SAVE_ON_REGS
  14963. +   if (!flag_all_mem_givs && !doing_loop_after_global
  14964. +      && !loop_contains_loop (loop_start, end) && flag_opt_reg_use)
  14965. +     {
  14966. +       bzero (reg_live_outside_loop, max_reg_before_loop);
  14967. +       mark_regs_live_outside (loop_start, end);
  14968. +     }
  14969. + #endif
  14970.     n_times_set = (short *) alloca (nregs * sizeof (short));
  14971.     n_times_used = (short *) alloca (nregs * sizeof (short));
  14972.     may_not_optimize = (char *) alloca (nregs);
  14973. ***************
  14974. *** 591,597 ****
  14975.   
  14976.     count_loop_regs_set (loop_top ? loop_top : loop_start, end,
  14977.                  may_not_optimize, reg_single_usage, &insn_count, nregs);
  14978.     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  14979.       may_not_optimize[i] = 1, n_times_set[i] = 1;
  14980.     bcopy ((char *) n_times_set, (char *) n_times_used, nregs * sizeof (short));
  14981. --- 726,733 ----
  14982.   
  14983.     count_loop_regs_set (loop_top ? loop_top : loop_start, end,
  14984.                  may_not_optimize, reg_single_usage, &insn_count, nregs);
  14985. !   /* intel1 added if but not body */
  14986. !   if (!doing_loop_after_global)
  14987.     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  14988.       may_not_optimize[i] = 1, n_times_set[i] = 1;
  14989.     bcopy ((char *) n_times_set, (char *) n_times_used, nregs * sizeof (short));
  14990. ***************
  14991. *** 644,649 ****
  14992. --- 780,787 ----
  14993.       in_libcall = 0;
  14994.   
  14995.         if (GET_CODE (p) == INSN
  14996. +           /* intel1 */
  14997. +       && (!doing_loop_after_global || GET_CODE(PATTERN(p)) == SET)
  14998.         && (set = single_set (p))
  14999.         && GET_CODE (SET_DEST (set)) == REG
  15000.         && ! may_not_optimize[REGNO (SET_DEST (set))])
  15001. ***************
  15002. *** 695,705 ****
  15003.         else if (! ((! maybe_never
  15004.                  && ! loop_reg_used_before_p (set, p, loop_start,
  15005.                               scan_start, end))
  15006. !               || (! REG_USERVAR_P (SET_DEST (set))
  15007. !               && ! REG_LOOP_TEST_P (SET_DEST (set)))
  15008.                 || reg_in_basic_block_p (p, SET_DEST (set))))
  15009.           ;
  15010. !       else if ((tem = invariant_p (src))
  15011.              && (dependencies == 0
  15012.                  || (tem2 = invariant_p (dependencies)) != 0)
  15013.              && (n_times_set[REGNO (SET_DEST (set))] == 1
  15014. --- 833,851 ----
  15015.         else if (! ((! maybe_never
  15016.                  && ! loop_reg_used_before_p (set, p, loop_start,
  15017.                               scan_start, end))
  15018. !               ||  (!doing_loop_after_global 
  15019. !                    && /* intel1 */!REG_USERVAR_P (SET_DEST (set))
  15020. !                    && ! REG_LOOP_TEST_P (SET_DEST (set)))
  15021.                 || reg_in_basic_block_p (p, SET_DEST (set))))
  15022.           ;
  15023. !       else if (((tem = invariant_p (src))
  15024. !                  /* intel1 */ || (doing_loop_after_global 
  15025. !                  && RTX_IS_SPILL_P (p) == 1 && spill_invariant_p (src))
  15026. !                )
  15027. !                /* intel1 */
  15028. !                     && !(doing_loop_after_global 
  15029. !                 && call_used_regs[REGNO (SET_DEST (set))]
  15030. !                 && loop_has_call)
  15031.              && (dependencies == 0
  15032.                  || (tem2 = invariant_p (dependencies)) != 0)
  15033.              && (n_times_set[REGNO (SET_DEST (set))] == 1
  15034. ***************
  15035. *** 749,754 ****
  15036. --- 895,901 ----
  15037.                might span a call.  */
  15038.             && ! modified_between_p (SET_SRC (set), p,
  15039.                          reg_single_usage[regno])
  15040. +           && !doing_loop_after_global /* intel1 */
  15041.             && no_labels_between_p (p, reg_single_usage[regno])
  15042.             && validate_replace_rtx (SET_DEST (set), SET_SRC (set),
  15043.                          reg_single_usage[regno]))
  15044. ***************
  15045. *** 966,977 ****
  15046. --- 1113,1137 ----
  15047.     move_movables (movables, threshold,
  15048.            insn_count, loop_start, end, nregs);
  15049.   
  15050. +   /* intel1 */
  15051. +   if (doing_loop_after_global && !loop_has_call)
  15052. +     {
  15053. +       move_spills_out(loop_start, end, nregs);
  15054. +     }
  15055.     /* Now candidates that still are negative are those not moved.
  15056.        Change n_times_set to indicate that those are not actually invariant.  */
  15057.     for (i = 0; i < nregs; i++)
  15058.       if (n_times_set[i] < 0)
  15059.         n_times_set[i] = n_times_used[i];
  15060.   
  15061. +   /*intel1 */
  15062. + #ifdef SAVE_ON_REGS
  15063. +    if (!doing_loop_after_global && flag_opt_reg_use)
  15064. +    {
  15065. +      use_regs_source(loop_start, end, 1); 
  15066. +    }
  15067. + #endif
  15068.     if (flag_strength_reduce)
  15069.       strength_reduce (scan_start, end, loop_top,
  15070.                insn_count, loop_start, end);
  15071. ***************
  15072. *** 1257,1263 ****
  15073.             /* A reg used for zero-extending mustn't be eliminated.  */
  15074.             && !m1->partial
  15075.             && (matched_regs[m1->regno]
  15076. !           ||
  15077.             (
  15078.              /* Can combine regs with different modes loaded from the
  15079.                 same constant only if the modes are the same or
  15080. --- 1417,1423 ----
  15081.             /* A reg used for zero-extending mustn't be eliminated.  */
  15082.             && !m1->partial
  15083.             && (matched_regs[m1->regno]
  15084. !           || 
  15085.             (
  15086.              /* Can combine regs with different modes loaded from the
  15087.                 same constant only if the modes are the same or
  15088. ***************
  15089. *** 1534,1539 ****
  15090. --- 1694,1706 ----
  15091.        rtx end;
  15092.        int nregs;
  15093.   {
  15094. + /* intel1 */
  15095. + #ifdef SAVE_ON_REGS
  15096. +   rtx sinsn,last_sym;
  15097. +   int num_sym_adds;
  15098. + #endif
  15099. +   /* intel1 */
  15100. +   int *insns_deleted;
  15101.     rtx new_start = 0;
  15102.     register struct movable *m;
  15103.     register rtx p;
  15104. ***************
  15105. *** 1548,1553 ****
  15106. --- 1715,1760 ----
  15107.   
  15108.     num_movables = 0;
  15109.   
  15110. +   /* intel1 */
  15111. +   num_movables = 0;
  15112. + /* intel1 Any insn moved out of loop must be deleted from the log_links
  15113. +           of all other insns in the loop.
  15114. + */
  15115. +   if (doing_loop_after_global)
  15116. +     {
  15117. +         insns_deleted = (int *) alloca ((max_uid_for_loop+1) * sizeof (int));
  15118. +         bzero(insns_deleted,(max_uid_for_loop+1) * sizeof (int));
  15119. +     }
  15120. + /* intel1 */
  15121. + #ifdef SAVE_ON_REGS
  15122. +   num_sym_adds=0;
  15123. +   last_sym = NULL;
  15124. +   for (sinsn=loop_start;flag_opt_reg_use && (sinsn!=end && num_sym_adds < 2);
  15125. +         sinsn=NEXT_INSN (sinsn))
  15126. +      {
  15127. +         if (GET_CODE (sinsn) == INSN
  15128. +            && GET_CODE (PATTERN (sinsn)) == SET
  15129. +            && GET_CODE (SET_DEST (PATTERN (sinsn))) == REG
  15130. +            && GET_CODE (SET_SRC (PATTERN (sinsn))) == PLUS
  15131. +            && GET_CODE (XEXP (SET_SRC (PATTERN (sinsn)), 0)) == REG
  15132. +            && GET_CODE (XEXP (SET_SRC (PATTERN (sinsn)), 1)) == SYMBOL_REF)
  15133. +       {
  15134. +         if (last_sym)
  15135. +       {
  15136. +         if (!rtx_equal_p (XEXP (SET_SRC (PATTERN (sinsn)), 1),
  15137. +                         last_sym))
  15138. +           {
  15139. +             num_sym_adds++;
  15140. +           }
  15141. +       }
  15142. +         else
  15143. +       {
  15144. +         last_sym = XEXP (SET_SRC (PATTERN (sinsn)), 1);
  15145. +       }
  15146. +       }
  15147. +     }
  15148. + #endif /* SAVE_ON_REGS */
  15149.     for (m = movables; m; m = m->next)
  15150.       {
  15151.         /* Describe this movable insn.  */
  15152. ***************
  15153. *** 1626,1632 ****
  15154.   
  15155.         /* It is also desirable to move if it can be moved at no
  15156.            extra cost because something else was already moved.  */
  15157.         if (already_moved[regno]
  15158.             || (threshold * savings * m->lifetime) >= insn_count
  15159.             || (m->forces && m->forces->done
  15160. --- 1833,1862 ----
  15161.   
  15162.         /* It is also desirable to move if it can be moved at no
  15163.            extra cost because something else was already moved.  */
  15164. ! #ifdef SAVE_ON_REGS
  15165. !         /* intel1 if the insn is regx <- regy + symbol_ref then don't move
  15166. !            if there is more than one.  
  15167. !         */
  15168. !         if (flag_opt_reg_use
  15169. !            && num_sym_adds > 1 
  15170. !            && GET_CODE (PATTERN (m->insn)) == SET 
  15171. !            && GET_CODE (SET_DEST (PATTERN (m->insn))) == REG 
  15172. !            && GET_CODE (SET_SRC (PATTERN (m->insn))) == PLUS 
  15173. !            && GET_CODE (XEXP (SET_SRC (PATTERN (m->insn)), 0)) == REG 
  15174. !            && GET_CODE (XEXP (SET_SRC (PATTERN (m->insn)), 1)) == SYMBOL_REF)
  15175. !         {
  15176. !           savings = 0;
  15177. !         } 
  15178. ! #endif           
  15179. ! /* intel1 */
  15180. ! #ifdef STACK_REGS
  15181. ! #ifdef IS_STACK_MODE
  15182. !           if (IS_STACK_MODE (DFmode)
  15183. !              && GET_CODE (PATTERN (m->insn)) == SET 
  15184. !              && GET_CODE (SET_SRC (PATTERN (m->insn))) == CONST_DOUBLE)
  15185. !             savings = 0; /* not worthwhile */
  15186. ! #endif
  15187. ! #endif
  15188.         if (already_moved[regno]
  15189.             || (threshold * savings * m->lifetime) >= insn_count
  15190.             || (m->forces && m->forces->done
  15191. ***************
  15192. *** 1659,1669 ****
  15193. --- 1889,1912 ----
  15194.             regs_may_share = gen_rtx (EXPR_LIST, VOIDmode, r1,
  15195.                           gen_rtx (EXPR_LIST, VOIDmode, r2,
  15196.                                regs_may_share));
  15197. +                   /* intel1 */
  15198. +                   if (doing_loop_after_global 
  15199. +                      && INSN_UID (m->insn) <= max_uid_for_loop)
  15200. +                     {
  15201. +                       insns_deleted[INSN_UID (m->insn)] = 1;
  15202. +                     }
  15203.             delete_insn (m->insn);
  15204.   
  15205.             if (new_start == 0)
  15206.               new_start = i1;
  15207.   
  15208. +                   /* intel1 */
  15209. +                   if (doing_loop_after_global)
  15210. +                     {
  15211. +                       RTX_IS_SPILL_P (i1) = RTX_IS_SPILL_P (m->insn);
  15212. +                       SPILL_PSEUDO (i1) = SPILL_PSEUDO (m->insn);
  15213. +                     }
  15214. +                     
  15215.             if (loop_dump_stream)
  15216.               fprintf (loop_dump_stream, " moved to %d", INSN_UID (i1));
  15217.           }
  15218. ***************
  15219. *** 1690,1697 ****
  15220.               {
  15221.                 temp = XEXP (temp, 0);
  15222.                 while (temp != p)
  15223. !                 temp = delete_insn (temp);
  15224.               }
  15225.   
  15226.                 p = delete_insn (p);
  15227.                 while (p && GET_CODE (p) == NOTE)
  15228. --- 1933,1954 ----
  15229.               {
  15230.                 temp = XEXP (temp, 0);
  15231.                 while (temp != p)
  15232. !               {
  15233. !                   /* intel1 */
  15234. !                   if (doing_loop_after_global
  15235. !                       && INSN_UID( temp) <= max_uid_for_loop)
  15236. !                   {
  15237. !                        insns_deleted[INSN_UID( temp)] = 1;
  15238. !                   }
  15239. !                 temp = delete_insn (temp);
  15240. !               }
  15241.               }
  15242. +                /* intel1 */
  15243. +              if (doing_loop_after_global
  15244. +                 && INSN_UID( p) <= max_uid_for_loop)
  15245. +              {
  15246. +                  insns_deleted[INSN_UID( p)] = 1;
  15247. +               }
  15248.   
  15249.                 p = delete_insn (p);
  15250.                 while (p && GET_CODE (p) == NOTE)
  15251. ***************
  15252. *** 1712,1717 ****
  15253. --- 1969,1981 ----
  15254.                    m->is_equiv ? REG_EQUIV : REG_EQUAL,
  15255.                    m->set_src, REG_NOTES (i1));
  15256.   
  15257. +                   /* intel1 */
  15258. +                   if (doing_loop_after_global)
  15259. +                     {
  15260. +                       RTX_IS_SPILL_P (i1) = RTX_IS_SPILL_P (m->insn);
  15261. +                       SPILL_PSEUDO (i1) = SPILL_PSEUDO (m->insn);
  15262. +                     }
  15263.             if (loop_dump_stream)
  15264.               fprintf (loop_dump_stream, " moved to %d", INSN_UID (i1));
  15265.   
  15266. ***************
  15267. *** 1813,1818 ****
  15268. --- 2077,2088 ----
  15269.                     if (temp == fn_address_insn)
  15270.                   fn_address_insn = i1;
  15271.                     REG_NOTES (i1) = REG_NOTES (temp);
  15272. +                               /* intel1 */
  15273. +                               if (doing_loop_after_global 
  15274. +                                  && INSN_UID (temp) <= max_uid_for_loop)
  15275. +                                 {
  15276. +                                   insns_deleted[INSN_UID (temp)] = 1;
  15277. +                                 }
  15278.                     delete_insn (temp);
  15279.                   }
  15280.               }
  15281. ***************
  15282. *** 1868,1873 ****
  15283. --- 2138,2150 ----
  15284.                 if (new_start == 0)
  15285.               new_start = i1;
  15286.   
  15287. +                       /* intel1 */
  15288. +                       if (doing_loop_after_global)
  15289. +                         {
  15290. +                           RTX_IS_SPILL_P (i1) = RTX_IS_SPILL_P (m->insn);
  15291. +                           SPILL_PSEUDO (i1) = SPILL_PSEUDO (m->insn);
  15292. +                         }
  15293. +                         
  15294.                 if (loop_dump_stream)
  15295.               fprintf (loop_dump_stream, " moved to %d",
  15296.                    INSN_UID (i1));
  15297. ***************
  15298. *** 1895,1900 ****
  15299. --- 2172,2183 ----
  15300.                 XEXP (temp, 0) = i1;
  15301.               }
  15302.   
  15303. +                       /* intel1 */
  15304. +                       if (doing_loop_after_global 
  15305. +                          && INSN_UID (p) <= max_uid_for_loop)
  15306. +                         {
  15307. +                           insns_deleted[INSN_UID (p)] = 1;
  15308. +                         }
  15309.                 delete_insn (p);
  15310.                 do p = NEXT_INSN (p);
  15311.                 while (p && GET_CODE (p) == NOTE);
  15312. ***************
  15313. *** 1959,1966 ****
  15314.               {
  15315.                 for (temp = XEXP (temp, 0); temp != m1->insn;
  15316.                      temp = NEXT_INSN (temp))
  15317. !                 delete_insn (temp);
  15318.               }
  15319.                 delete_insn (m1->insn);
  15320.   
  15321.                 /* Any other movable that loads the same register
  15322. --- 2242,2263 ----
  15323.               {
  15324.                 for (temp = XEXP (temp, 0); temp != m1->insn;
  15325.                      temp = NEXT_INSN (temp))
  15326. !                 {
  15327. !                               /* intel1 */
  15328. !                               if (doing_loop_after_global 
  15329. !                                  && INSN_UID (temp) <= max_uid_for_loop)
  15330. !                                 {
  15331. !                                   insns_deleted[INSN_UID (temp)] = 1;
  15332. !                                 }
  15333. !                   delete_insn (temp);
  15334. !                 }
  15335.               }
  15336. +                       /* intel1 */
  15337. +                       if (doing_loop_after_global 
  15338. +                          && INSN_UID (m1->insn) <= max_uid_for_loop)
  15339. +                         {
  15340. +                           insns_deleted[INSN_UID (m1->insn)] = 1;
  15341. +                         }
  15342.                 delete_insn (m1->insn);
  15343.   
  15344.                 /* Any other movable that loads the same register
  15345. ***************
  15346. *** 1996,2001 ****
  15347. --- 2293,2326 ----
  15348.       replace_regs (REG_NOTES (p), reg_map, nregs, 0);
  15349.       INSN_CODE (p) = -1;
  15350.         }
  15351. +   /* intel1 */
  15352. +   /* remove all deleted insns from the log_links of any insn in which
  15353. +      they appear */
  15354. +   if (doing_loop_after_global)
  15355. +     {
  15356. +         int i;
  15357. +         rtx rn,prev,link;
  15358. +         for (rn=loop_start; rn!=end; rn=NEXT_INSN (rn))
  15359. +           {
  15360. +               if ((GET_CODE (rn) == INSN || GET_CODE (rn) == JUMP_INSN
  15361. +                    || GET_CODE (rn) == CALL_INSN) && LOG_LINKS(rn))
  15362. +                 {
  15363. +                     for (prev = 0, link = LOG_LINKS (rn); link;
  15364. +                          prev = link, link = XEXP (link, 1))
  15365. +                       {
  15366. +                           if (insns_deleted[INSN_UID(XEXP (link, 0))])
  15367. +                         {
  15368. +                           if (prev)
  15369. +                             XEXP (prev, 1) = XEXP (link, 1);
  15370. +                           else
  15371. +                             LOG_LINKS (rn) = XEXP (link, 1);
  15372. +                         }
  15373. +                       }
  15374. +                 }
  15375. +           }
  15376. +     }
  15377.   }
  15378.   
  15379.   #if 0
  15380. ***************
  15381. *** 2246,2252 ****
  15382.           loop_outer_loop[next_loop] = current_loop;
  15383.           loop_invalid[next_loop] = 0;
  15384.           loop_number_exit_labels[next_loop] = 0;
  15385. -         loop_number_exit_count[next_loop] = 0;
  15386.           current_loop = next_loop;
  15387.           break;
  15388.   
  15389. --- 2571,2576 ----
  15390. ***************
  15391. *** 2278,2283 ****
  15392. --- 2602,2610 ----
  15393.         uid_loop_num[INSN_UID (insn)] = current_loop;
  15394.       }
  15395.   
  15396. +             /* This loop will be continued with NEXT_INSN (insn).  */
  15397. +             insn = PREV_INSN (insn);
  15398.     /* Any loop containing a label used in an initializer must be invalidated,
  15399.        because it can be jumped into from anywhere.  */
  15400.   
  15401. ***************
  15402. *** 2291,2296 ****
  15403. --- 2618,2634 ----
  15404.       loop_invalid[loop_num] = 1;
  15405.       }
  15406.   
  15407. + #if HAVE_movstricthi
  15408. +   if (flag_sign_extension_elim)
  15409. +     {
  15410. +       int i;
  15411. +       for (i = max_loop_num-1; i >= 0; i--)
  15412. +         if (! loop_invalid[i] && loop_number_loop_ends[i])
  15413. +           sign_extension_reduction (loop_number_loop_starts[i],
  15414. +                                     loop_number_loop_ends [i]);
  15415. +     }
  15416. + #endif
  15417.     /* Now scan all insn's in the function.  If any JUMP_INSN branches into a
  15418.        loop that it is not contained within, that loop is marked invalid.
  15419.        If any INSN or CALL_INSN uses a label's address, then the loop containing
  15420. ***************
  15421. *** 2304,2314 ****
  15422.        label in our loop and will simplify processing by both us and a
  15423.        possible second cse pass.  */
  15424.   
  15425.     for (insn = f; insn; insn = NEXT_INSN (insn))
  15426.       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
  15427.         {
  15428.       int this_loop_num = uid_loop_num[INSN_UID (insn)];
  15429.       if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
  15430.         {
  15431.           rtx note = find_reg_note (insn, REG_LABEL, NULL_RTX);
  15432. --- 2642,2653 ----
  15433.        label in our loop and will simplify processing by both us and a
  15434.        possible second cse pass.  */
  15435.   
  15436.     for (insn = f; insn; insn = NEXT_INSN (insn))
  15437.       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
  15438.         {
  15439.       int this_loop_num = uid_loop_num[INSN_UID (insn)];
  15440. !         
  15441.       if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
  15442.         {
  15443.           rtx note = find_reg_note (insn, REG_LABEL, NULL_RTX);
  15444. ***************
  15445. *** 2338,2345 ****
  15446.         {
  15447.           rtx p;
  15448.           rtx our_next = next_real_insn (insn);
  15449. -         int dest_loop;
  15450. -         int outer_loop = -1;
  15451.   
  15452.           /* Go backwards until we reach the start of the loop, a label,
  15453.              or a JUMP_INSN.  */
  15454. --- 2677,2682 ----
  15455. ***************
  15456. *** 2351,2377 ****
  15457.            p = PREV_INSN (p))
  15458.             ;
  15459.   
  15460. !         /* Check for the case where we have a jump to an inner nested
  15461. !            loop, and do not perform the optimization in that case.  */
  15462. !         if (JUMP_LABEL (insn))
  15463. !           {
  15464. !         dest_loop = uid_loop_num[INSN_UID (JUMP_LABEL (insn))];
  15465. !         if (dest_loop != -1)
  15466. !           {
  15467. !             for (outer_loop = dest_loop; outer_loop != -1;
  15468. !              outer_loop = loop_outer_loop[outer_loop])
  15469. !               if (outer_loop == this_loop_num)
  15470. !             break;
  15471. !           }
  15472. !           }
  15473. !         /* Make sure that the target of P is within the current loop.  */
  15474. !         if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p)
  15475. !         && uid_loop_num[INSN_UID (JUMP_LABEL (p))] != this_loop_num)
  15476. !           outer_loop = this_loop_num;
  15477.           /* If we stopped on a JUMP_INSN to the next insn after INSN,
  15478.              we have a block of code to try to move.
  15479.   
  15480. --- 2688,2719 ----
  15481.            p = PREV_INSN (p))
  15482.             ;
  15483.   
  15484. !           /* intel1 */
  15485. !             if (flag_opt_jumps_out)
  15486. !               {
  15487. !                 /* Retarget a jump around a sequence that contains jumps out 
  15488. !                    of loop to jump out of the loop rather than jump around.  */
  15489. !                 while (!(GET_CODE (p) == JUMP_INSN
  15490. !                 && JUMP_LABEL (p) != 0
  15491. !                 && condjump_p (p)
  15492. !                 && ! simplejump_p (p)
  15493. !                 && next_real_insn (JUMP_LABEL (p)) == our_next
  15494. !                ) &&
  15495. !               !(GET_CODE (p) == JUMP_INSN 
  15496. !                 && (JUMP_LABEL (p) == 0 
  15497. !                  || (uid_loop_num[INSN_UID (JUMP_LABEL (p))]
  15498. !                 == this_loop_num))
  15499. !                ) 
  15500. !               && GET_CODE (p) != CODE_LABEL 
  15501. !               && !(GET_CODE (p) == NOTE
  15502. !                    && NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_BEG) 
  15503. !               && !(GET_CODE (p) == NOTE
  15504. !                    && NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)
  15505. !              )
  15506. !                   {
  15507. !                     p = PREV_INSN (p);
  15508. !                   }
  15509. !               }
  15510.           /* If we stopped on a JUMP_INSN to the next insn after INSN,
  15511.              we have a block of code to try to move.
  15512.   
  15513. ***************
  15514. *** 2381,2388 ****
  15515.              of the block, invert the jump in P and point it to that label,
  15516.              and move the block of code to the spot we found.  */
  15517.   
  15518. !         if (outer_loop == -1
  15519. !         && GET_CODE (p) == JUMP_INSN
  15520.           && JUMP_LABEL (p) != 0
  15521.           /* Just ignore jumps to labels that were never emitted.
  15522.              These always indicate compilation errors.  */
  15523. --- 2723,2729 ----
  15524.              of the block, invert the jump in P and point it to that label,
  15525.              and move the block of code to the spot we found.  */
  15526.   
  15527. !         if (GET_CODE (p) == JUMP_INSN
  15528.           && JUMP_LABEL (p) != 0
  15529.           /* Just ignore jumps to labels that were never emitted.
  15530.              These always indicate compilation errors.  */
  15531. ***************
  15532. *** 2407,2413 ****
  15533.               && uid_loop_num[INSN_UID (loc)] == target_loop_num)
  15534.                 break;
  15535.   
  15536. !         if (loc)
  15537.             {
  15538.               rtx cond_label = JUMP_LABEL (p);
  15539.               rtx new_label = get_label_after (p);
  15540. --- 2748,2762 ----
  15541.               && uid_loop_num[INSN_UID (loc)] == target_loop_num)
  15542.                 break;
  15543.   
  15544. !         if (loc 
  15545. !              ||
  15546. !             /* intel1 Enable the optimization even if no barier
  15547. !                       is found.  This requires adding a jump
  15548. !                       around the section of code moved out - but
  15549. !                       this can win if jumps NOT taken are preferred.  
  15550. !             */
  15551. !             (flag_opt_jumps_out 
  15552. !                  && LABEL_NUSES (JUMP_LABEL (p)) == 1))
  15553.             {
  15554.               rtx cond_label = JUMP_LABEL (p);
  15555.               rtx new_label = get_label_after (p);
  15556. ***************
  15557. *** 2424,2430 ****
  15558.                  /* Include the BARRIER after INSN and copy the
  15559.                 block after LOC.  */
  15560.                  new_label = squeeze_notes (new_label, NEXT_INSN (insn));
  15561. !                reorder_insns (new_label, NEXT_INSN (insn), loc);
  15562.   
  15563.                  /* All those insns are now in TARGET_LOOP_NUM.  */
  15564.                  for (q = new_label; q != NEXT_INSN (NEXT_INSN (insn));
  15565. --- 2773,2784 ----
  15566.                  /* Include the BARRIER after INSN and copy the
  15567.                 block after LOC.  */
  15568.                  new_label = squeeze_notes (new_label, NEXT_INSN (insn));
  15569. !                /* intel1 */
  15570. !                if (loc)
  15571. !                  reorder_insns (new_label, NEXT_INSN (insn), loc);
  15572. !                else
  15573. !                  reorder_insns (new_label, NEXT_INSN (insn), 
  15574. !                               PREV_INSN (target));
  15575.   
  15576.                  /* All those insns are now in TARGET_LOOP_NUM.  */
  15577.                  for (q = new_label; q != NEXT_INSN (NEXT_INSN (insn));
  15578. ***************
  15579. *** 2438,2445 ****
  15580.                 LABEL_OUTSIDE_LOOP_P bit.  */
  15581.                  if (JUMP_LABEL (insn))
  15582.                {
  15583. -                int loop_num;
  15584.                  for (q = 0,
  15585.                   r = loop_number_exit_labels[this_loop_num];
  15586.                   r; q = r, r = LABEL_NEXTREF (r))
  15587. --- 2792,2797 ----
  15588. ***************
  15589. *** 2454,2464 ****
  15590.                    break;
  15591.                      }
  15592.   
  15593. -                for (loop_num = this_loop_num;
  15594. -                 loop_num != -1 && loop_num != target_loop_num;
  15595. -                 loop_num = loop_outer_loop[loop_num])
  15596. -                  loop_number_exit_count[loop_num]--;
  15597.                  /* If we didn't find it, then something is wrong. */
  15598.                  if (! r)
  15599.                    abort ();
  15600. --- 2806,2811 ----
  15601. ***************
  15602. *** 2468,2481 ****
  15603.                 in loop_number_exit_labels, and marked as such.
  15604.                 The easiest way to do this is to just call
  15605.                 mark_loop_jump again for P.  */
  15606.                  mark_loop_jump (PATTERN (p), this_loop_num);
  15607. !                /* If INSN now jumps to the insn after it,
  15608. !               delete INSN.  */
  15609. !                if (JUMP_LABEL (insn) != 0
  15610. !                && (next_real_insn (JUMP_LABEL (insn))
  15611. !                    == next_real_insn (insn)))
  15612. !              delete_insn (insn);
  15613.                }
  15614.   
  15615.               /* Continue the loop after where the conditional
  15616. --- 2815,2838 ----
  15617.                 in loop_number_exit_labels, and marked as such.
  15618.                 The easiest way to do this is to just call
  15619.                 mark_loop_jump again for P.  */
  15620. +         
  15621.                  mark_loop_jump (PATTERN (p), this_loop_num);
  15622. !                        /* intel1 */
  15623. !                        if (loc)
  15624. !                          {
  15625. !                    /* If INSN now jumps to the insn after it,
  15626. !                   delete INSN.  */
  15627. !                    if (JUMP_LABEL (insn) != 0
  15628. !                    && (next_real_insn (JUMP_LABEL (insn))
  15629. !                        == next_real_insn (insn)))
  15630. !                  delete_insn (insn);
  15631. !              }
  15632. !                else
  15633. !                  {
  15634. !                    /* move the jump insn to just before the new_label */
  15635. !                    reorder_insns (insn, NEXT_INSN (insn),
  15636. !                                   PREV_INSN (new_label));
  15637. !                  }
  15638.                }
  15639.   
  15640.               /* Continue the loop after where the conditional
  15641. ***************
  15642. *** 2484,2494 ****
  15643.                  branch and hence needs no processing.  */
  15644.               insn = NEXT_INSN (cond_label);
  15645.   
  15646. !             if (--LABEL_NUSES (cond_label) == 0)
  15647. !               delete_insn (cond_label);
  15648. !             /* This loop will be continued with NEXT_INSN (insn).  */
  15649. !             insn = PREV_INSN (insn);
  15650.             }
  15651.             }
  15652.         }
  15653. --- 2841,2856 ----
  15654.                  branch and hence needs no processing.  */
  15655.               insn = NEXT_INSN (cond_label);
  15656.   
  15657. !                        /* intel1 */
  15658. !                     if (loc)
  15659. !                       {
  15660. !                 if (--LABEL_NUSES (cond_label) == 0)
  15661. !                   delete_insn (cond_label);
  15662. !                }
  15663. !              else
  15664. !                {
  15665. !                   delete_insn (cond_label);
  15666. !                }
  15667.             }
  15668.             }
  15669.         }
  15670. ***************
  15671. *** 2546,2573 ****
  15672.        mark this LABEL_REF so we know that this branch should predict
  15673.        false.  */
  15674.   
  15675. !       /* A check to make sure the label is not in an inner nested loop,
  15676. !      since this does not count as a loop exit.  */
  15677. !       if (dest_loop != -1)
  15678. !     {
  15679. !       for (outer_loop = dest_loop; outer_loop != -1;
  15680. !            outer_loop = loop_outer_loop[outer_loop])
  15681. !         if (outer_loop == loop_num)
  15682. !           break;
  15683. !     }
  15684. !       else
  15685. !     outer_loop = -1;
  15686. !       if (loop_num != -1 && outer_loop == -1)
  15687.       {
  15688.         LABEL_OUTSIDE_LOOP_P (x) = 1;
  15689.         LABEL_NEXTREF (x) = loop_number_exit_labels[loop_num];
  15690.         loop_number_exit_labels[loop_num] = x;
  15691. -       for (outer_loop = loop_num;
  15692. -            outer_loop != -1 && outer_loop != dest_loop;
  15693. -            outer_loop = loop_outer_loop[outer_loop])
  15694. -         loop_number_exit_count[outer_loop]++;
  15695.       }
  15696.   
  15697.         /* If this is inside a loop, but not in the current loop or one enclosed
  15698. --- 2908,2918 ----
  15699.        mark this LABEL_REF so we know that this branch should predict
  15700.        false.  */
  15701.   
  15702. !       if (dest_loop != loop_num && loop_num != -1)
  15703.       {
  15704.         LABEL_OUTSIDE_LOOP_P (x) = 1;
  15705.         LABEL_NEXTREF (x) = loop_number_exit_labels[loop_num];
  15706.         loop_number_exit_labels[loop_num] = x;
  15707.       }
  15708.   
  15709.         /* If this is inside a loop, but not in the current loop or one enclosed
  15710. ***************
  15711. *** 2593,2599 ****
  15712. --- 2938,2953 ----
  15713.                "\nLoop at %d ignored due to multiple entry points.\n",
  15714.                INSN_UID (loop_number_loop_starts[dest_loop]));
  15715.         
  15716. +       /* intel1
  15717. +          If doing loop_spl we don't care if there are multiple jumps
  15718. +          to the loop entry label.  */
  15719. +       if (!doing_spl 
  15720. +           || NEXT_INSN (loop_number_loop_starts[dest_loop]) 
  15721. +                != XEXP (x, 0))
  15722. +       {
  15723. +         
  15724.         loop_invalid[dest_loop] = 1;
  15725. +       }
  15726.       }
  15727.         return;
  15728.   
  15729. ***************
  15730. *** 2624,2636 ****
  15731.        as a branch out of this loop, but not into any loop.  */
  15732.   
  15733.         if (loop_num != -1)
  15734. !     {
  15735. !       loop_number_exit_labels[loop_num] = x;
  15736.   
  15737. -       for (outer_loop = loop_num; outer_loop != -1;
  15738. -            outer_loop = loop_outer_loop[outer_loop])
  15739. -         loop_number_exit_count[outer_loop]++;
  15740. -     }
  15741.         return;
  15742.       }
  15743.   }
  15744. --- 2978,2985 ----
  15745.        as a branch out of this loop, but not into any loop.  */
  15746.   
  15747.         if (loop_num != -1)
  15748. !     loop_number_exit_labels[loop_num] = x;
  15749.   
  15750.         return;
  15751.       }
  15752.   }
  15753. ***************
  15754. *** 2818,2824 ****
  15755.     return 1 + conditional;
  15756.   }
  15757.   
  15758.   /* Return nonzero if all the insns in the loop that set REG
  15759.      are INSN and the immediately following insns,
  15760.      and if each of those insns sets REG in an invariant way
  15761. --- 3167,3172 ----
  15762. ***************
  15763. *** 3047,3052 ****
  15764. --- 3395,3416 ----
  15765.               may_not_move[regno] = 1;
  15766.             if (n_times_set[regno] < 127)
  15767.               ++n_times_set[regno];
  15768. +           /* intel1 */
  15769. +           if (doing_loop_after_global 
  15770. +              && HARD_REGNO_NREGS (regno, GET_MODE (dest)) > 1)
  15771. +             { /* Count each hard reg in the group.  */
  15772. +                 register int i,next_regno;
  15773. +                 i = HARD_REGNO_NREGS (regno, GET_MODE (dest));
  15774. +                 next_regno = regno + 1;
  15775. +                 while (i!=1)
  15776. +                   {
  15777. +                       if (n_times_set[next_regno] < 127)
  15778. +                         ++n_times_set[next_regno];
  15779. +                       next_regno++;
  15780. +                       i--;
  15781. +                   }
  15782. +             }
  15783.             last_set[regno] = insn;
  15784.           }
  15785.           }
  15786. ***************
  15787. *** 3244,3249 ****
  15788. --- 3608,3616 ----
  15789.     int call_seen;
  15790.     rtx test;
  15791.     rtx end_insert_before;
  15792. +   int try_compare_elimination, done_compare_elimination; /* intel1 */
  15793. +   rtx compare_insn, jump_insn, tinsn; /* intel1 */
  15794. +   int *times_reg_used; /* intel1 */
  15795.     int loop_depth = 0;
  15796.   
  15797.     reg_iv_type = (enum iv_mode *) alloca (max_reg_before_loop
  15798. ***************
  15799. *** 3373,3379 ****
  15800.            will be executed if the loop is executed.  */
  15801.         && ! (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p) == loop_top
  15802.           && ((NEXT_INSN (NEXT_INSN (p)) == loop_end && simplejump_p (p))
  15803. !             || (NEXT_INSN (p) == loop_end && condjump_p (p)))))
  15804.       not_every_iteration = 1;
  15805.   
  15806.         else if (GET_CODE (p) == NOTE)
  15807. --- 3740,3749 ----
  15808.            will be executed if the loop is executed.  */
  15809.         && ! (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p) == loop_top
  15810.           && ((NEXT_INSN (NEXT_INSN (p)) == loop_end && simplejump_p (p))
  15811. !           || (NEXT_INSN (p) == loop_end && condjump_p (p))))
  15812. !      /*intel1*/  && !(GET_CODE (p) == JUMP_INSN
  15813. !                       && jumps_back_in_loop(p,loop_start,0,0))
  15814. !     )
  15815.       not_every_iteration = 1;
  15816.   
  15817.         else if (GET_CODE (p) == NOTE)
  15818. ***************
  15819. *** 3487,3492 ****
  15820. --- 3857,3874 ----
  15821.       }
  15822.       }
  15823.   
  15824. +   /* Now see if it is wothwhile to do compare elimination, remember it only
  15825. +      saves one instruction.  intel1
  15826. +   */
  15827. +   try_compare_elimination = 0;
  15828. +   if (flag_compare_elim 
  15829. +      && loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]] == NULL)
  15830. +   {
  15831. +     possible_compare_elimination(loop_start, loop_end, &compare_insn, 
  15832. +                                  &jump_insn, &try_compare_elimination);
  15833. +     done_compare_elimination = 0;
  15834. +   }
  15835.     /* Look at the each biv and see if we can say anything better about its
  15836.        initial value from any initializing insns set up above.  (This is done
  15837.        in two passes to avoid missing SETs in a PARALLEL.)  */
  15838. ***************
  15839. *** 3508,3513 ****
  15840. --- 3890,3910 ----
  15841.          || GET_MODE (src) == VOIDmode)
  15842.         && valid_initial_value_p (src, bl->init_insn, call_seen, loop_start))
  15843.       {
  15844. +       /* intel1 */
  15845. +       if (flag_compare_elim && !flag_unroll_loops 
  15846. +          && try_compare_elimination && !done_compare_elimination 
  15847. +          && bl->biv_count == 1 
  15848. +          && bl->biv->mult_val == const1_rtx 
  15849. +          && REGNO (XEXP (SET_SRC (PATTERN (compare_insn)), 0)) == bl->regno 
  15850. +          &&  (done_compare_elimination 
  15851. +          = compare_elimination (bl, loop_start, loop_end, 
  15852. +                              compare_insn, jump_insn,0)))
  15853. +         {
  15854. +               rtx tem = find_reg_note (bl->init_insn, REG_EQUAL, 0);
  15855. +           if (tem)
  15856. +         XEXP (tem, 0) = SET_SRC (bl->init_set);
  15857. +           src = SET_SRC (bl->init_set);
  15858. +         }
  15859.         bl->initial_value = src;
  15860.   
  15861.         if (loop_dump_stream)
  15862. ***************
  15863. *** 3651,3657 ****
  15864.            will be executed if the loop is executed.  */
  15865.         && ! (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p) == loop_top
  15866.           && ((NEXT_INSN (NEXT_INSN (p)) == loop_end && simplejump_p (p))
  15867. !             || (NEXT_INSN (p) == loop_end && condjump_p (p)))))
  15868.       not_every_iteration = 1;
  15869.   
  15870.         else if (GET_CODE (p) == NOTE)
  15871. --- 4048,4057 ----
  15872.            will be executed if the loop is executed.  */
  15873.         && ! (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p) == loop_top
  15874.           && ((NEXT_INSN (NEXT_INSN (p)) == loop_end && simplejump_p (p))
  15875. !           || (NEXT_INSN (p) == loop_end && condjump_p (p))))
  15876. !      /*intel1*/ && !(GET_CODE (p) == JUMP_INSN
  15877. !                      && jumps_back_in_loop(p,loop_start,0,0))
  15878. !     )
  15879.       not_every_iteration = 1;
  15880.   
  15881.         else if (GET_CODE (p) == NOTE)
  15882. ***************
  15883. *** 3717,3722 ****
  15884. --- 4117,4128 ----
  15885.     for (bl = loop_iv_list; bl; bl = bl->next)
  15886.       {
  15887.         struct induction *v;
  15888. +       /* intel1 */
  15889. + #ifdef SAVE_ON_REGS
  15890. +       int num_add_vals_live_outside =0;
  15891. +       int no_mem_givs = 0;
  15892. +       int contains_loop =0;
  15893. + #endif
  15894.         int benefit;
  15895.         int all_reduced;
  15896.         rtx final_value = 0;
  15897. ***************
  15898. *** 3774,3779 ****
  15899. --- 4180,4276 ----
  15900.        We can't (currently) eliminate the biv unless this is so.  */
  15901.         all_reduced = 1;
  15902.   
  15903. +       /* intel1 */
  15904. + #ifdef SAVE_ON_REGS
  15905. +       /* Only reduce DEST_ADDR givs of this biv if they will not increase
  15906. +          register pressure.  
  15907. +       */
  15908. +       if (!flag_all_mem_givs && flag_opt_reg_use)
  15909. +         {
  15910. +           int num_mult_val_saved = 0;
  15911. +           int num_givs_to_update = 0;
  15912. +           num_add_vals_live_outside = 0;
  15913. +           no_mem_givs = 0;
  15914. +           contains_loop = loop_contains_loop (loop_start, end);
  15915. +         
  15916. +           for (v = bl->giv; v; v = v->next_iv)
  15917. +             {
  15918. +               if (v->giv_type == DEST_ADDR)
  15919. +                 num_mult_val_saved++;
  15920. +               if (v->giv_type == DEST_ADDR && !v->same)
  15921. +                 {
  15922. +                   num_givs_to_update++;
  15923. +                   if (v->add_val && GET_CODE (v->add_val) == REG 
  15924. +                      && REGNO (v->add_val) >= FIRST_PSEUDO_REGISTER 
  15925. +                      && (contains_loop 
  15926. +                          || REGNO (v->add_val)<max_reg_before_loop))
  15927. +                     {
  15928. +                       if (loop_dump_stream 
  15929. +                          && reg_live_outside_loop[REGNO (v->add_val)])
  15930. +                         {
  15931. +                           fprintf (loop_dump_stream, 
  15932. +                           "dest addr giv at %d has add_val live outside reg%d\n", 
  15933. +                           INSN_UID (v->insn), REGNO (v->add_val));
  15934. +                         }
  15935. +                       if (contains_loop)
  15936. +                         num_add_vals_live_outside += 2;
  15937. +                       else
  15938. +                         {
  15939. +                           num_add_vals_live_outside += 
  15940. +                             reg_live_outside_loop[REGNO (v->add_val)];
  15941. +                         }
  15942. +                     }
  15943. +                   else if (v->add_val && GET_CODE (v->add_val) == CONST_INT 
  15944. +                            && v->mult_val == const1_rtx)
  15945. +                     { /* Disable this reduction. */
  15946. +                       num_add_vals_live_outside = (1 << ((sizeof (int)*8)-4));
  15947. +                     }
  15948. +                 }
  15949. +             }
  15950. + #ifdef MAX_DEST_ADDR_GIVS
  15951. +         if (num_givs_to_update > MAX_DEST_ADDR_GIVS)
  15952. +           {
  15953. +             no_mem_givs = 1;
  15954. +           }
  15955. + #endif
  15956. +         /* Heuristic here:
  15957. +            a) If the biv is eliminated that saves one register in the loop.  
  15958. +            b) Each giv_to_update must be updated at the end of the loop.  
  15959. +            c) Each add_val_live_outside may cause a spill somewhere.  
  15960. +         */
  15961. +         if (loop_dump_stream)
  15962. +           {
  15963. +             fprintf (loop_dump_stream,
  15964. +             "eliminable %d num_updates %d mults_saved %d adds_outside %d heu %d\n",
  15965. +             bl->eliminable, num_givs_to_update, num_mult_val_saved,
  15966. +             num_add_vals_live_outside,
  15967. +             (((int)(bl->eliminable) * -3) 
  15968. +              + (num_givs_to_update+((int)(bl->eliminable) * -1)) 
  15969. +              + (num_mult_val_saved*-1) +
  15970. +              + (num_add_vals_live_outside*3) 
  15971. +             ));
  15972. +           }
  15973. +         if (no_mem_givs 
  15974. +             ||  
  15975. +             (((int)(bl->eliminable) * -3) 
  15976. +              + (num_givs_to_update+((int)(bl->eliminable) * -1)) 
  15977. +              + (num_mult_val_saved*-1) +
  15978. +              + (num_add_vals_live_outside*3) > 0
  15979. +             )
  15980. +            )
  15981. +           {
  15982. +             all_reduced = 0;
  15983. +             for (v = bl->giv; v; v = v->next_iv)
  15984. +               {
  15985. +                 if (v->giv_type == DEST_ADDR)
  15986. +                   {
  15987. +                     v->ignore = 1;
  15988. +                   }
  15989. +               }
  15990. +           }
  15991. +       }
  15992. + #endif /* SAVE_ON_REGS */
  15993.         /* Check each giv in this class to see if we will benefit by reducing
  15994.        it.  Skip giv's combined with others.  */
  15995.         for (v = bl->giv; v; v = v->next_iv)
  15996. ***************
  15997. *** 3965,3971 ****
  15998.            loop to ensure that it will always be executed no matter
  15999.            how the loop exits.  Otherwise, emit the insn after the loop,
  16000.            since this is slightly more efficient.  */
  16001. !           if (loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]])
  16002.           insert_before = loop_start;
  16003.             else
  16004.           insert_before = end_insert_before;
  16005. --- 4462,4468 ----
  16006.            loop to ensure that it will always be executed no matter
  16007.            how the loop exits.  Otherwise, emit the insn after the loop,
  16008.            since this is slightly more efficient.  */
  16009. !           if (loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]])
  16010.           insert_before = loop_start;
  16011.             else
  16012.           insert_before = end_insert_before;
  16013. ***************
  16014. *** 4032,4037 ****
  16015. --- 4529,4542 ----
  16016.        of the occurrences of the biv with a giv, but no harm was done in
  16017.        doing so in the rare cases where it can occur.  */
  16018.   
  16019. +       /* intel1 Retry compare elimination this time for loop trip test.  */
  16020. +       if (flag_compare_elim && !flag_unroll_loops 
  16021. +          && !done_compare_elimination && bl->retry_celim > 1 
  16022. +          && all_reduced == 1 && bl->eliminable)
  16023. +         {
  16024. +       compare_elimination (bl, loop_start, loop_end, 
  16025. +                           compare_insn, jump_insn, 1);
  16026. +         } 
  16027.         if (all_reduced == 1 && bl->eliminable
  16028.         && maybe_eliminate_biv (bl, loop_start, end, 1,
  16029.                     threshold, insn_count))
  16030. ***************
  16031. *** 4057,4063 ****
  16032.            loop to ensure that it will always be executed no matter
  16033.            how the loop exits.  Otherwise, emit the insn after the
  16034.            loop, since this is slightly more efficient.  */
  16035. !           if (loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]])
  16036.           insert_before = loop_start;
  16037.             else
  16038.           insert_before = end_insert_before;
  16039. --- 4562,4568 ----
  16040.            loop to ensure that it will always be executed no matter
  16041.            how the loop exits.  Otherwise, emit the insn after the
  16042.            loop, since this is slightly more efficient.  */
  16043. !           if (loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]])
  16044.           insert_before = loop_start;
  16045.             else
  16046.           insert_before = end_insert_before;
  16047. ***************
  16048. *** 4083,4088 ****
  16049. --- 4588,4606 ----
  16050.           fprintf (loop_dump_stream, "Reg %d: biv eliminated\n",
  16051.                bl->regno);
  16052.       }
  16053. +       /* intel1 Retry compare elimination this time handling ashifhts. */
  16054. +       else if (flag_compare_elim && !flag_unroll_loops 
  16055. +                && !done_compare_elimination && bl->retry_celim == 1)
  16056. +         {
  16057. +       if (compare_elimination (bl, loop_start, loop_end, 
  16058. +                              compare_insn, jump_insn, 1))
  16059. +         {
  16060. +               rtx tem = find_reg_note (bl->init_insn, REG_EQUAL, 0);
  16061. +           if (tem)
  16062. +         XEXP (tem, 0) = SET_SRC (bl->init_set);
  16063. +            bl->initial_value = SET_SRC (bl->init_set);;
  16064. +         }
  16065. +         } 
  16066.       }
  16067.   
  16068.     /* Go through all the instructions in the loop, making all the
  16069. ***************
  16070. *** 4164,4169 ****
  16071. --- 4682,4689 ----
  16072.     register int i, j;
  16073.     register enum rtx_code code;
  16074.     register char *fmt;
  16075. +   /* intel1 */
  16076. +   rtx tx;
  16077.   
  16078.     if (x == 0)
  16079.       return;
  16080. ***************
  16081. *** 4195,4200 ****
  16082. --- 4715,4738 ----
  16083.       benefit = general_induction_var (XEXP (x, 0),
  16084.                        &src_reg, &add_val, &mult_val);
  16085.   
  16086. +     /* intel1
  16087. +        For now lets strip off consty and try to recoginze the result
  16088. +        as a possible mem_giv.  */
  16089. + #ifdef REWRITE_ADDRESS
  16090. +     if (flag_opt_reg_use
  16091. +        && benefit == 0 && GET_CODE (XEXP (x, 0)) == PLUS 
  16092. +        && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS 
  16093. +        &&  (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 
  16094. +         || GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST 
  16095. +         || GET_CODE (XEXP (XEXP (x, 0), 1)) == SYMBOL_REF))
  16096. +       {
  16097. +         tx = x;
  16098. +         x = XEXP (x, 0);
  16099. +         benefit = general_induction_var (XEXP (x, 0),
  16100. +                                              &src_reg, &add_val, &mult_val);
  16101. +       }
  16102. + #endif
  16103.       /* Don't make a DEST_ADDR giv with mult_val == 1 && add_val == 0.
  16104.          Such a giv isn't useful.  */
  16105.       if (benefit > 0 && (mult_val != const1_rtx || add_val != const0_rtx))
  16106. ***************
  16107. *** 4203,4208 ****
  16108. --- 4741,4765 ----
  16109.           struct induction *v
  16110.             = (struct induction *) oballoc (sizeof (struct induction));
  16111.   
  16112. + /* intel1 */
  16113. + #ifdef REDUCE_INDEX
  16114. + #ifdef REWRITE_ADDRESS
  16115. + #ifdef LEGITIMATE_INDEX_P
  16116. +     rtx * index_part;
  16117. +     /* try to eliminate index terms */        
  16118. +     if (REDUCE_INDEX && flag_reduce_index_givs
  16119. +        && do_reduce_index (x, &add_val))
  16120. +       { 
  16121. +         index_part = &XEXP (XEXP (x, 0), 0);
  16122. +         record_giv (v, insn, src_reg, addr_placeholder, mult_val,
  16123. +                    add_val, benefit, DEST_ADDR, not_every_iteration,
  16124. +                    index_part, loop_start, loop_end);
  16125. +         v->is_index_induc = 1;
  16126. +       }
  16127. +     else
  16128. + #endif
  16129. + #endif
  16130. + #endif
  16131.           record_giv (v, insn, src_reg, addr_placeholder, mult_val,
  16132.               add_val, benefit, DEST_ADDR, not_every_iteration,
  16133.               &XEXP (x, 0), loop_start, loop_end);
  16134. ***************
  16135. *** 4290,4295 ****
  16136. --- 4847,4854 ----
  16137.         bl->eliminable = 0;
  16138.         bl->nonneg = 0;
  16139.         bl->reversed = 0;
  16140. +       /* intel1 */
  16141. +       bl->retry_celim = 0;
  16142.         bl->total_benefit = 0;
  16143.   
  16144.         /* Add this class to loop_iv_list.  */
  16145. ***************
  16146. *** 4374,4379 ****
  16147. --- 4933,4942 ----
  16148.     v->new_reg = 0;
  16149.     v->final_value = 0;
  16150.     v->same_insn = 0;
  16151. +   /* intel1 */
  16152. + #ifdef REDUCE_INDEX
  16153. +   v->is_index_induc = 0;
  16154. + #endif
  16155.   
  16156.     /* The v->always_computable field is used in update_giv_derive, to
  16157.        determine whether a giv can be used to derive another giv.  For a
  16158. ***************
  16159. *** 4651,4657 ****
  16160.   
  16161.             if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p)
  16162.             && LABEL_NAME (JUMP_LABEL (p))
  16163. !           && ((INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (v->insn)
  16164.                  && INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (loop_start))
  16165.                 || (INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (last_giv_use)
  16166.                 && INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (loop_end))))
  16167. --- 5214,5221 ----
  16168.   
  16169.             if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p)
  16170.             && LABEL_NAME (JUMP_LABEL (p))
  16171. !           && ( INSN_UID(v->insn)>=max_uid_for_loop /* intel1 */
  16172. !               || (INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (v->insn)
  16173.                  && INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (loop_start))
  16174.                 || (INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (last_giv_use)
  16175.                 && INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (loop_end))))
  16176. ***************
  16177. *** 5474,5482 ****
  16178.        the expression of G2 in terms of G1 can be used.  */
  16179.     if (g2->giv_type == DEST_ADDR
  16180.         && (tem = express_from (g1, g2)) != 0
  16181.         && memory_address_p (g2->mem_mode, tem)
  16182. !       && ADDRESS_COST (tem) <= ADDRESS_COST (*g2->location))
  16183.       {
  16184.         g2->new_reg = tem;
  16185.         return 1;
  16186.       }
  16187. --- 6038,6063 ----
  16188.        the expression of G2 in terms of G1 can be used.  */
  16189.     if (g2->giv_type == DEST_ADDR
  16190.         && (tem = express_from (g1, g2)) != 0
  16191. + /* intel1 */
  16192. + #ifdef REDUCE_INDEX
  16193. +       && ((g2->is_index_induc && LEGITIMATE_INDEX_P(tem)) 
  16194. +            || (g2->is_index_induc == 0 && memory_address_p (g2->mem_mode, tem)
  16195. +            && ADDRESS_COST (tem) <= ADDRESS_COST (*g2->location))
  16196. +          )
  16197. + #else
  16198.         && memory_address_p (g2->mem_mode, tem)
  16199. !       && ADDRESS_COST (tem) <= ADDRESS_COST (*g2->location)
  16200. ! #endif
  16201. !      )
  16202.       {
  16203. + /* intel1 */
  16204. + #ifdef SAVE_ON_REGS
  16205. +       
  16206. +       if (flag_opt_reg_use && ADDRESS_COST (tem) != 1)
  16207. +       {
  16208. +         return(0);
  16209. +       }
  16210. + #endif
  16211.         g2->new_reg = tem;
  16212.         return 1;
  16213.       }
  16214. ***************
  16215. *** 5772,5778 ****
  16216.         num_nonfixed_reads += count_nonfixed_reads (PATTERN (p));
  16217.   
  16218.         if (bl->giv_count == 0
  16219. !       && ! loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]])
  16220.       {
  16221.         rtx bivreg = regno_reg_rtx[bl->regno];
  16222.   
  16223. --- 6353,6359 ----
  16224.         num_nonfixed_reads += count_nonfixed_reads (PATTERN (p));
  16225.   
  16226.         if (bl->giv_count == 0
  16227. !       && ! loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]])
  16228.       {
  16229.         rtx bivreg = regno_reg_rtx[bl->regno];
  16230.   
  16231. ***************
  16232. *** 6274,6279 ****
  16233. --- 6855,6869 ----
  16234.         for (v = bl->giv; v; v = v->next_iv)
  16235.       if (v->giv_type == DEST_ADDR && v->location == &XEXP (x, 0))
  16236.         return 1;
  16237. + /* intel1 */
  16238. + #ifdef REDUCE_INDEX
  16239. + #ifdef LEGITIMATE_INDEX_P
  16240. +       for (v = bl->giv; v; v = v->next_iv)
  16241. +     if (REDUCE_INDEX && v->giv_type == DEST_ADDR && v->is_index_induc 
  16242. +         && v->location == &XEXP (XEXP(x,0), 0))
  16243. +       return 1;
  16244. + #endif
  16245. + #endif
  16246.         break;
  16247.       }
  16248.   
  16249. ***************
  16250. *** 6628,6631 ****
  16251. --- 7218,13765 ----
  16252.   
  16253.     return gen_rtx (swap_condition (GET_CODE (comparison)), VOIDmode,
  16254.             XEXP (comparison, 1), XEXP (comparison, 0));
  16255. + }
  16256. + /* new code added by intel1 */
  16257. + struct new_rtx
  16258. +   {
  16259. +     rtx pat;
  16260. +     rtx insn;
  16261. +     rtx supplemental_pat;    /* Pattern that should be
  16262. +                    emited after this insn.  */
  16263. +     struct new_rtx *next;
  16264. +   };
  16265. + /* If bl is also the loop counter try to optimize out the
  16266. +    compare instruction by counting up to 0.  Return 1 if
  16267. +    successful.
  16268. + */
  16269. + static
  16270. + int 
  16271. + compare_elimination (bl, loop_start, loop_end, compare_insn, jump_insn, second_time)
  16272. +      struct iv_class *bl;
  16273. +      rtx loop_start, loop_end, compare_insn, jump_insn;
  16274. +      int second_time;
  16275. + {
  16276. +   rtx insn, new_init_src, copy_of_jump, new_biv_set, loop_trip_reg;
  16277. +   int init_val, compare_val, i, adjust_val, desired_init_val;
  16278. +   int num_times_loop_execs, add_one, biv_init_to_const, biv_end_value;
  16279. +   int num_sups, compare_to_const;
  16280. +   struct new_rtx *new_rtx_element, *new_rtx_head, *new_rtx_tail;
  16281. +   char *storage;
  16282. +   if (GET_CODE (SET_DEST (bl->init_set)) != REG)
  16283. +     {
  16284. +       return (0);
  16285. +     }
  16286. +   if (!rtx_equal_p (SET_DEST (bl->init_set),
  16287. +             XEXP (SET_SRC (PATTERN (compare_insn)), 0))
  16288. +     )
  16289. +     {
  16290. +       return (0);
  16291. +     }
  16292. +   copy_of_jump = copy_rtx (PATTERN (jump_insn));
  16293. +   PUT_CODE (XEXP (SET_SRC (copy_of_jump), 0), NE);
  16294. +   if (recog (copy_of_jump, jump_insn, 0) == -1)
  16295. +     {
  16296. +       return (0);
  16297. +     }
  16298. +   if (GET_CODE (XEXP (SET_SRC (PATTERN (compare_insn)), 1)) == CONST_INT)
  16299. +     {
  16300. +       if (bl->initial_test != NULL)
  16301. +     {
  16302. +       return (0);
  16303. +     }
  16304. +       compare_val = INTVAL (XEXP (SET_SRC (PATTERN (compare_insn)), 1));
  16305. +       compare_to_const = 1;
  16306. +     }
  16307. +   else
  16308. +     {
  16309. +       compare_to_const = 0;
  16310. +       if (INTVAL (bl->biv->add_val) != 1)
  16311. +     {
  16312. +       return (0);
  16313. +     }
  16314. +       else if (second_time == 0)
  16315. +     {
  16316. +       bl->retry_celim = 2;    /* Signals that this is loop trip test
  16317. +                                candidate.  */
  16318. +       return (0);
  16319. +     }
  16320. +     }
  16321. +   if (GET_CODE (SET_SRC (bl->init_set)) != CONST_INT)
  16322. +     {
  16323. +       if (!compare_to_const)
  16324. +     {
  16325. +       return (0);
  16326. +     }
  16327. +       else
  16328. +     {
  16329. +       if (abs (INTVAL (bl->biv->add_val)) != 1)
  16330. +         {
  16331. +           return (0);
  16332. +         }
  16333. +       biv_init_to_const = 0;
  16334. +       /* Just so checks on LE GE ... pass.  */
  16335. +       init_val = compare_val - INTVAL (bl->biv->add_val);
  16336. +     }
  16337. +     }
  16338. +   else
  16339. +     {
  16340. +       init_val = INTVAL (SET_SRC (bl->init_set));
  16341. +       biv_init_to_const = 1;
  16342. +     }
  16343. +   insn = PREV_INSN (compare_insn);
  16344. +   while (GET_CODE (insn) == NOTE)
  16345. +     {
  16346. +       insn = PREV_INSN (insn);
  16347. +     }
  16348. +   if (!(GET_CODE (insn) == INSN 
  16349. +     && rtx_equal_p (SET_DEST (PATTERN (insn)), SET_DEST (bl->init_set)) 
  16350. +     && bl->biv->insn == insn))
  16351. +     {
  16352. +       return (0);
  16353. +     }
  16354. +   switch (GET_CODE (XEXP (SET_SRC (PATTERN (jump_insn)), 0)))
  16355. +     {
  16356. +     case LE:
  16357. +       if (compare_to_const 
  16358. +       && (INTVAL (bl->biv->add_val) <= 0 || compare_val < init_val))
  16359. +     {
  16360. +       return (0);
  16361. +     }
  16362. +       add_one = 1;
  16363. +       break;
  16364. +     case GE:
  16365. +       if (compare_to_const 
  16366. +       && (INTVAL (bl->biv->add_val) >= 0 || compare_val > init_val))
  16367. +     {
  16368. +       return (0);
  16369. +     }
  16370. +       add_one = 1;
  16371. +       break;
  16372. +     case LT:
  16373. +       if (compare_to_const 
  16374. +       && (INTVAL (bl->biv->add_val) <= 0 || compare_val <= init_val))
  16375. +     {
  16376. +       return (0);
  16377. +     }
  16378. +       add_one = 0;
  16379. +       break;
  16380. +     case GT:
  16381. +       if (compare_to_const 
  16382. +       && (INTVAL (bl->biv->add_val) >= 0 || compare_val >= init_val))
  16383. +     {
  16384. +       return (0);
  16385. +     }
  16386. +       add_one = 0;
  16387. +       break;
  16388. +     default:
  16389. +       return (0);
  16390. +     }
  16391. +   if (!compare_to_const)
  16392. +     { /* We are doing loop trip test.  */
  16393. +       if (n_times_set[REGNO (XEXP (SET_SRC (PATTERN (compare_insn)), 1))])
  16394. +     {
  16395. +       return (0);
  16396. +     }
  16397. +       loop_trip_reg = gen_reg_rtx (GET_MODE (SET_DEST (bl->init_set)));
  16398. +       desired_init_val = (-1 * init_val) + add_one;
  16399. +       /* Emit insn to initialize loop trip reg.  */
  16400. +       if (desired_init_val)
  16401. +     {
  16402. +       emit_insn_before (gen_rtx (SET, 0, loop_trip_reg,
  16403. +                      gen_rtx (PLUS, GET_MODE (loop_trip_reg),
  16404. +                  XEXP (SET_SRC (PATTERN (compare_insn)), 1),
  16405. +                  gen_rtx (CONST_INT, 0, desired_init_val))),
  16406. +                 loop_start);
  16407. +     }
  16408. +       else
  16409. +     {
  16410. +       emit_insn_before (gen_rtx (SET, 0, loop_trip_reg,
  16411. +                 XEXP (SET_SRC (PATTERN (compare_insn)), 1)),
  16412. +                 loop_start);
  16413. +     }
  16414. +       /* Emit insn to decrement loop trip reg.  */
  16415. +       emit_insn_before (gen_rtx (SET, 0, loop_trip_reg,
  16416. +                  gen_rtx (PLUS, GET_MODE (loop_trip_reg),
  16417. +                       loop_trip_reg,
  16418. +                       gen_rtx (CONST_INT, 0, -1))),
  16419. +             compare_insn);
  16420. +       /* Change comparison */
  16421. +       XEXP (SET_SRC (PATTERN (compare_insn)), 1) = const0_rtx;
  16422. +       XEXP (SET_SRC (PATTERN (compare_insn)), 0) = loop_trip_reg;
  16423. +       /* Change jump insn */
  16424. +       PUT_CODE (XEXP (SET_SRC (PATTERN (jump_insn)), 0), NE);
  16425. +       INSN_CODE (jump_insn) = recog (PATTERN (jump_insn), jump_insn, 0);
  16426. +       bl->retry_celim = 0;
  16427. +       return (1);
  16428. +     }
  16429. +   if (biv_init_to_const)
  16430. +     {
  16431. +       num_times_loop_execs
  16432. +       = ((abs (compare_val - init_val) + add_one - 1) / abs (INTVAL (bl->biv->add_val))) + 1;
  16433. +       desired_init_val = -1 * num_times_loop_execs * INTVAL (bl->biv->add_val);
  16434. +       adjust_val = init_val - desired_init_val;
  16435. +       new_init_src = gen_rtx (CONST_INT, 0, desired_init_val);
  16436. +       biv_end_value = num_times_loop_execs * INTVAL (bl->biv->add_val) + init_val;
  16437. +     }
  16438. +   else
  16439. +     {/* biv is incremented by +-1 so the adjust_val is */
  16440. +       adjust_val 
  16441. +       = (compare_val + (add_one * INTVAL (bl->biv->add_val)));
  16442. +       desired_init_val = -1 * adjust_val;
  16443. +       biv_end_value = compare_val + (add_one * INTVAL (bl->biv->add_val));
  16444. +       /* Make a check that we will be able to adjust the bivs init_val
  16445. +          by desired_init_val.  */
  16446. +       new_init_src = gen_rtx (PLUS, GET_MODE (SET_DEST (bl->init_set)),
  16447. +                   SET_SRC (bl->init_set),
  16448. +                   gen_rtx (CONST_INT, 0, desired_init_val));
  16449. +       new_biv_set = gen_rtx (SET, GET_MODE (SET_SRC (bl->init_set)),
  16450. +                  SET_DEST (bl->init_set), new_init_src);
  16451. +       if (recog (new_biv_set, bl->init_set, 0) == -1)
  16452. +     {
  16453. +       return (0);
  16454. +     }
  16455. +     }
  16456. +   /* Now see if we can replace register bl->regno with
  16457. +      bl->regno+(adjust_val) in all insns from bl->init_insn to
  16458. +      loop_end.  
  16459. +      Signal that if we fail we should retry again at the end of
  16460. +      strength reduction.  */
  16461. +   if (second_time == 0)
  16462. +     {
  16463. +       bl->retry_celim = 1;
  16464. +     }
  16465. +   /* Mark our place on the obstack in case of failure.  */
  16466. +   storage = (char *) oballoc (0);
  16467. +   num_sups = 0;
  16468. +   new_rtx_head = new_rtx_tail = NULL;
  16469. +   insn = NEXT_INSN (bl->init_insn);
  16470. +   while (insn != compare_insn)
  16471. +     {
  16472. +       if (GET_CODE (insn) == INSN 
  16473. +       && !rtx_equal_p (SET_DEST (PATTERN (insn)), SET_DEST (bl->init_set)))
  16474. +     {
  16475. +       new_rtx_element = (struct new_rtx *) alloca (sizeof (struct new_rtx));
  16476. +       new_rtx_element->insn = insn;
  16477. +       new_rtx_element->supplemental_pat = NULL;
  16478. +       if (!attempt_new_rtx (new_rtx_element, insn, bl, adjust_val, second_time))
  16479. +         {
  16480. +           obfree (storage);
  16481. +           return (0);
  16482. +         }
  16483. +       else if (!rtx_equal_p (SET_SRC (insn), SET_SRC (new_rtx_element->pat)) 
  16484. +         || !rtx_equal_p (SET_DEST (insn), SET_DEST (new_rtx_element->pat)))
  16485. +         {
  16486. +           if (new_rtx_head == NULL)
  16487. +         {
  16488. +           new_rtx_head = new_rtx_element;
  16489. +         }
  16490. +           else
  16491. +         {
  16492. +           new_rtx_tail->next = new_rtx_element;
  16493. +         }
  16494. +           new_rtx_tail = new_rtx_element;
  16495. +           new_rtx_element->next = 0;
  16496. +         }
  16497. +       if (new_rtx_element->supplemental_pat)
  16498. +         {
  16499. +           num_sups++;
  16500. +           if (num_sups > 3)
  16501. +         { /* heuristic */
  16502. +           obfree (storage);
  16503. +           return (0);
  16504. +         }
  16505. +         }
  16506. +     }
  16507. +       insn = NEXT_INSN (insn);
  16508. +     }
  16509. +   /* Replacement can be done now do it.  */
  16510. +   new_rtx_element = new_rtx_head;
  16511. +   while (new_rtx_element)
  16512. +     {
  16513. +       PATTERN (new_rtx_element->insn) = new_rtx_element->pat;
  16514. +       if (new_rtx_element->supplemental_pat)
  16515. +     {
  16516. +       emit_insn_after (
  16517. +         gen_move_insn (SET_DEST (new_rtx_element->supplemental_pat),
  16518. +                    SET_SRC (new_rtx_element->supplemental_pat)),
  16519. +                 new_rtx_element->insn);
  16520. +     }
  16521. +       new_rtx_element = new_rtx_element->next;
  16522. +     }
  16523. +   /* Finally update the initialization and comparison of the biv.  */
  16524. +   PUT_CODE (XEXP (SET_SRC (PATTERN (jump_insn)), 0), NE);
  16525. +   INSN_CODE (jump_insn) = recog (PATTERN (jump_insn), jump_insn, 0);
  16526. +   XEXP (SET_SRC (PATTERN (compare_insn)), 1) = const0_rtx;
  16527. +   SET_SRC (bl->init_set) = new_init_src;
  16528. +   INSN_CODE (bl->init_insn) = recog ( PATTERN (bl->init_insn), bl->init_insn, 0);
  16529. +   emit_insn_after (gen_rtx (SET, GET_MODE (SET_DEST (bl->init_set)),
  16530. +                 SET_DEST (bl->init_set),
  16531. +                 gen_rtx (CONST_INT, 0, biv_end_value)),
  16532. +            loop_end);
  16533. +   bl->retry_celim = 0;
  16534. +   return (1);
  16535. + }
  16536. + /* Try to rewrite insn replacing the biv with biv+biv_adjust_const.  if
  16537. +    the substitution is not immediately recognizable then try to
  16538. +    rewrite the insn to make it recognizable.  If try_supplemental is 1
  16539. +    then an additional insn may be generated to make the substitution
  16540. +    recognizable.  The generated pattern is pointed to by
  16541. +    new_rtx_element->pat.  
  16542. + */
  16543. + static 
  16544. + attempt_new_rtx (new_rtx_element, insn, bl, biv_adjust_const, try_supplemental)
  16545. +      rtx insn;
  16546. +      struct new_rtx *new_rtx_element;
  16547. +      struct iv_class *bl;
  16548. +      int biv_adjust_const;
  16549. +      int try_supplemental;
  16550. + {
  16551. +   rtx new_src, new_dest, make_new_use (), try_to_make_good ();
  16552. +   new_src 
  16553. +      = make_new_use (SET_SRC (PATTERN (insn)), SET_DEST (bl->init_set),
  16554. +           biv_adjust_const, insn);
  16555. +   new_dest 
  16556. +     = make_new_use (SET_DEST (PATTERN (insn)), SET_DEST (bl->init_set),
  16557. +           biv_adjust_const, insn);
  16558. +   new_rtx_element->pat = gen_rtx (SET, 0, new_dest, new_src);
  16559. +   if (recog (new_rtx_element->pat, insn, 0) < 0)
  16560. +     {
  16561. +       try_to_make_good (SET_SRC (new_rtx_element->pat));
  16562. +       try_to_make_good (SET_DEST (new_rtx_element->pat));
  16563. +     }
  16564. +   if (recog (new_rtx_element->pat, insn, 0) < 0)
  16565. +     {
  16566. +       if (!try_supplemental)
  16567. +     {
  16568. +       return (0);
  16569. +     }
  16570. +       if (GET_CODE (SET_DEST (new_rtx_element->pat)) == REG 
  16571. +       && GET_CODE (SET_SRC (new_rtx_element->pat)) == ASHIFT 
  16572. +       && GET_CODE (XEXP (SET_SRC (new_rtx_element->pat), 0)) == PLUS 
  16573. +       && GET_CODE (XEXP (SET_SRC (new_rtx_element->pat), 1)) == CONST_INT 
  16574. +           && GET_CODE (XEXP (XEXP (SET_SRC (new_rtx_element->pat), 0), 0)) == REG 
  16575. +       && GET_CODE (XEXP (XEXP (SET_SRC (new_rtx_element->pat), 0), 1)) == CONST_INT
  16576. +     )
  16577. +     {
  16578. +       /* try to rewrite:
  16579. +            (set (reg:SI x)
  16580. +               (ashift:SI (plus:SI (reg/v:SI y)
  16581. +                                   (const_int a))
  16582. +                          (const_int b)))
  16583. +            into two patterns:
  16584. +            (set (reg:SI x)
  16585. +               (ashift:SI (reg/v:SI y)
  16586. +                          (const_int b)))
  16587. +            (set (reg:SI x)
  16588. +               (plus:SI (reg/v:SI x)
  16589. +                        (const_int a*(2**b))))
  16590. +         */
  16591. +       int add_val;
  16592. +       add_val 
  16593. +         = two_to_power (INTVAL (XEXP (SET_SRC (new_rtx_element->pat), 1))) 
  16594. +           * INTVAL (XEXP (XEXP (SET_SRC (new_rtx_element->pat), 0), 1));
  16595. +       new_rtx_element->pat = PATTERN (new_rtx_element->insn);
  16596. +       new_rtx_element->supplemental_pat 
  16597. +         = gen_rtx (SET, GET_MODE (SET_DEST (new_rtx_element->pat)),
  16598. +              SET_DEST (new_rtx_element->pat),
  16599. +       gen_rtx (PLUS, GET_MODE (XEXP (SET_SRC (new_rtx_element->pat), 0)),
  16600. +            SET_DEST (new_rtx_element->pat),
  16601. +            gen_rtx (CONST_INT, 0, add_val)));
  16602. +     }
  16603. +       else if (GET_CODE (SET_DEST (new_rtx_element->pat)) == REG 
  16604. +            && GET_CODE (SET_SRC (new_rtx_element->pat)) == PLUS 
  16605. +            && GET_CODE (XEXP (SET_SRC (new_rtx_element->pat), 0)) == REG 
  16606. +            && GET_CODE (XEXP (SET_SRC (new_rtx_element->pat), 1)) == PLUS 
  16607. +            && GET_CODE (XEXP (XEXP (SET_SRC (new_rtx_element->pat), 1), 0)) == REG 
  16608. +            && GET_CODE (XEXP (XEXP (SET_SRC (new_rtx_element->pat), 1), 1)) == CONST_INT
  16609. +     )
  16610. +     {
  16611. +       /* try to rewrite:
  16612. +            (set (reg:SI x)
  16613. +                 (plus:SI (reg:SI y)
  16614. +                           (plus:SI   (reg:SI z)
  16615. +                                      (const_int a))))
  16616. +            into two patterns:
  16617. +            (set (reg:SI x)
  16618. +               (plus:SI (reg/v:SI y)
  16619. +                        (reg/v:SI z)))
  16620. +            (set (reg:SI x)
  16621. +               (plus:SI (reg/v:SI x)
  16622. +                        (const_int a)))
  16623. +         */
  16624. +       new_rtx_element->supplemental_pat 
  16625. +         = gen_rtx (SET, GET_MODE (SET_DEST (new_rtx_element->pat)),
  16626. +              SET_DEST (new_rtx_element->pat),
  16627. +       gen_rtx (PLUS, GET_MODE (XEXP (SET_SRC (new_rtx_element->pat), 0)),
  16628. +            SET_DEST (new_rtx_element->pat),
  16629. +            XEXP (XEXP (SET_SRC (new_rtx_element->pat), 1), 1)));
  16630. +       new_rtx_element->pat = PATTERN (new_rtx_element->insn);
  16631. +     }
  16632. +       else
  16633. +     {
  16634. +       return (0);
  16635. +     }
  16636. +       if (recog (new_rtx_element->supplemental_pat, insn, 0) < 0)
  16637. +     {
  16638. +       return (0);
  16639. +     }
  16640. +     }
  16641. +   return (1);
  16642. + }
  16643. + /* Generate a new rtx which is a copy of orig with each occurence of
  16644. +    biv_reg replaced by biv_reg+biv_adjust_const.  
  16645. + */
  16646. + static rtx
  16647. + make_new_use (orig, biv_reg, biv_adjust_const, insn)
  16648. +      register rtx orig, biv_reg;
  16649. +      rtx insn;
  16650. +      int biv_adjust_const;
  16651. + {
  16652. +   register rtx copy;
  16653. +   rtx non_biv_operand, ret_rtx;
  16654. +   register int i, j;
  16655. +   register RTX_CODE code;
  16656. +   register char *format_ptr;
  16657. +   code = GET_CODE (orig);
  16658. +   switch (code)
  16659. +     {
  16660. +     case REG:
  16661. +       if (rtx_equal_p (orig, biv_reg))
  16662. +     {
  16663. +       ret_rtx 
  16664. +         = gen_rtx (PLUS, GET_MODE (orig), orig,
  16665. +              gen_rtx (CONST_INT, 0, biv_adjust_const));
  16666. +       return (ret_rtx);
  16667. +     }
  16668. +       else
  16669. +     {
  16670. +       return (orig);
  16671. +     }
  16672. +       break;
  16673. +     case PLUS:
  16674. +     case MINUS:
  16675. +       if (GET_CODE (XEXP (orig, 0)) == REG && GET_CODE (XEXP (orig, 1)) == CONST_INT 
  16676. +       && rtx_equal_p (XEXP (orig, 0), biv_reg))
  16677. +     { /* Ajdust the const_int part by biv_adjust_const.  */
  16678. +       if (GET_CODE (orig) == PLUS)
  16679. +         {
  16680. +           non_biv_operand 
  16681. +            = gen_rtx (CONST_INT, 0,
  16682. +              INTVAL (XEXP (orig, 1)) + biv_adjust_const);
  16683. +         }
  16684. +       else
  16685. +         {
  16686. +           non_biv_operand 
  16687. +         = gen_rtx (CONST_INT, 0,
  16688. +              INTVAL (XEXP (orig, 1)) - biv_adjust_const);
  16689. +         }
  16690. +       ret_rtx = gen_rtx (code, GET_MODE (orig), XEXP (orig, 0), non_biv_operand);
  16691. +       return (ret_rtx);
  16692. +     }
  16693. +       else
  16694. +     /* commutativity */ 
  16695. +     if (GET_CODE (XEXP (orig, 1)) == REG && GET_CODE (XEXP (orig, 0)) == CONST_INT 
  16696. +         && rtx_equal_p (XEXP (orig, 1), biv_reg))
  16697. +     {/* Ajdust the const_int part by biv_adjust_const.  */
  16698. +       if (GET_CODE (orig) == PLUS)
  16699. +         {
  16700. +           non_biv_operand 
  16701. +         = gen_rtx (CONST_INT, 0,
  16702. +              INTVAL (XEXP (orig, 0)) + biv_adjust_const);
  16703. +         }
  16704. +       else
  16705. +         {
  16706. +           non_biv_operand 
  16707. +         = gen_rtx (CONST_INT, 0,
  16708. +              INTVAL (XEXP (orig, 0)) - biv_adjust_const);
  16709. +         }
  16710. +       ret_rtx = gen_rtx (code, GET_MODE (orig), non_biv_operand, XEXP (orig, 1));
  16711. +       return (ret_rtx);
  16712. +     }
  16713. +       break;
  16714. +     case QUEUED:
  16715. +     case CONST_INT:
  16716. +     case CONST_DOUBLE:
  16717. +     case SYMBOL_REF:
  16718. +     case CODE_LABEL:
  16719. +     case PC:
  16720. +     case CC0:
  16721. +       return orig;
  16722. +     }
  16723. +   copy = rtx_alloc (code);
  16724. +   PUT_MODE (copy, GET_MODE (orig));
  16725. +   copy->in_struct = orig->in_struct;
  16726. +   copy->volatil = orig->volatil;
  16727. +   copy->unchanging = orig->unchanging;
  16728. +   copy->integrated = orig->integrated;
  16729. +   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
  16730. +   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
  16731. +     {
  16732. +       switch (*format_ptr++)
  16733. +     {
  16734. +     case 'e':
  16735. +       XEXP (copy, i) = XEXP (orig, i);
  16736. +       if (XEXP (orig, i) != NULL)
  16737. +         XEXP (copy, i) 
  16738. +           = make_new_use (XEXP (orig, i), biv_reg,
  16739. +                 biv_adjust_const, insn);
  16740. +       break;
  16741. +     case 'E':
  16742. +     case 'V':
  16743. +       XVEC (copy, i) = XVEC (orig, i);
  16744. +       if (XVEC (orig, i) != NULL)
  16745. +         {
  16746. +           XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
  16747. +           for (j = 0; j < XVECLEN (copy, i); j++)
  16748. +         XVECEXP (copy, i, j) 
  16749. +           = make_new_use (XVECEXP (orig, i, j), biv_reg,
  16750. +                 biv_adjust_const, insn);
  16751. +         }
  16752. +       break;
  16753. +     default:
  16754. +       XINT (copy, i) = XINT (orig, i);
  16755. +       break;
  16756. +     }
  16757. +     }
  16758. +   return copy;
  16759. + }
  16760. + /* Try to put orig into a form that is recognizable using rewrite_address
  16761. +    on the relevant portion of orig.  
  16762. + */
  16763. + rtx
  16764. + try_to_make_good (orig)
  16765. +      register rtx orig;
  16766. + {
  16767. +   void rewrite_address ();
  16768. +   register int i, j;
  16769. +   register RTX_CODE code;
  16770. +   register char *fmt;
  16771. +   code = GET_CODE (orig);
  16772. +   switch (code)
  16773. +     {
  16774. +     case REG:
  16775. +     case QUEUED:
  16776. +     case CONST_INT:
  16777. +     case CONST_DOUBLE:
  16778. +     case SYMBOL_REF:
  16779. +     case CODE_LABEL:
  16780. +     case PC:
  16781. +     case CC0:
  16782. +       return orig;
  16783. +     case MEM:
  16784. +       GO_IF_LEGITIMATE_ADDRESS (GET_MODE (orig), orig, memok);
  16785. + #ifdef REWRITE_ADDRESS
  16786. +       REWRITE_ADDRESS (orig);
  16787. + #endif
  16788. +     memok:
  16789. +       return (orig);
  16790. +     }
  16791. +   fmt = GET_RTX_FORMAT (code);
  16792. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  16793. +     if (fmt[i] == 'e')
  16794. +       XEXP (orig, i) = try_to_make_good (XEXP (orig, i));
  16795. +     else if (fmt[i] == 'E' || fmt[i] == 'V')
  16796. +       {
  16797. +     for (j = 0; j < XVECLEN (orig, i); j++)
  16798. +       XVECEXP (orig, i, j) 
  16799. +         = try_to_make_good (XVECEXP (orig, i, j));
  16800. +       }
  16801. +   return orig;
  16802. + }
  16803. + /* Check to see if compare elimination is possible for this loop.  
  16804. +    Return 1 if yes and set up *compare_insn to point to the compare
  16805. +    at the end of the loop and *jump_insn to point to the jump back
  16806. +    to the beginning of the loop.  
  16807. + */
  16808. + static int
  16809. + possible_compare_elimination (loop_start, loop_end, compare_insn, jump_insn, try_compare_elimination)
  16810. +      rtx loop_end, loop_start, *compare_insn, *jump_insn;
  16811. +      int *try_compare_elimination;
  16812. + {
  16813. +   rtx insn;
  16814. +   int i;
  16815. +   insn = loop_start;
  16816. +   i = 0;
  16817. +   *try_compare_elimination = 0;
  16818. +   while (insn && insn != loop_end)
  16819. +     {
  16820. +       if (GET_CODE (insn) == CALL_INSN)
  16821. +     {
  16822. +       insn = NULL;
  16823. +     }
  16824. +       else if (GET_CODE (insn) == INSN)
  16825. +     {
  16826. +       i++;
  16827. +       if (i > MAX_CMP_ELIM)
  16828. +         {
  16829. +           insn = NULL;
  16830. +         }
  16831. +       else if (GET_CODE (PATTERN (insn)) != SET)
  16832. +         {
  16833. +           insn = NULL;
  16834. +         }
  16835. +     }
  16836. +       if (insn)
  16837. +     insn = NEXT_INSN (insn);
  16838. +     }
  16839. +   if (insn != NULL)
  16840. +     {
  16841. +       *try_compare_elimination = 1;
  16842. +     }
  16843. +   /* Look for compare jcc on this biv at the end of the loop.  */
  16844. +   insn = PREV_INSN (loop_end);
  16845. +   if (!(GET_CODE (insn) == JUMP_INSN 
  16846. +     && GET_CODE (PATTERN (insn)) == SET 
  16847. +     && SET_DEST (PATTERN (insn)) == pc_rtx 
  16848. +     && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE 
  16849. +     && XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0) == cc0_rtx 
  16850. +     && XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 1) == const0_rtx))
  16851. +     {
  16852. +       *try_compare_elimination = 0;
  16853. +     }
  16854. +   *jump_insn = insn;
  16855. +   insn = PREV_INSN (insn);
  16856. +   if (!(GET_CODE (insn) == INSN 
  16857. +     && GET_CODE (PATTERN (insn)) == SET 
  16858. +     && SET_DEST (PATTERN (insn)) == cc0_rtx 
  16859. +     && GET_CODE (SET_SRC (PATTERN (insn))) == COMPARE 
  16860. +     && (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT 
  16861. +         || GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == REG) 
  16862. +     && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG))
  16863. +     {
  16864. +       *try_compare_elimination = 0;
  16865. +     }
  16866. +   *compare_insn = insn;
  16867. + }
  16868. + struct regs_mentioned
  16869. +   {
  16870. +     rtx reg;                /* The register.  */
  16871. +     int in_mem;                /* Is 1 if register is part of
  16872. +                            a MEM_REF.  */
  16873. +     struct regs_mentioned *next;
  16874. +   };
  16875. +    
  16876. + static struct regs_mentioned *giv_reg_header = NULL, *use_reg_header = NULL;
  16877. + /* Build a linked list of (struct regs_mentioned) describing the
  16878. +    registers used in the pattern pat.  The head of the linked list
  16879. +    to place them on is a_header.  If in_mem is 1 this means that
  16880. +    pat is subexpression of a MEM_REF.  
  16881. + */
  16882. + static void
  16883. + find_regs_mentioned (pat, a_header, in_mem)
  16884. +      rtx pat;
  16885. +      struct regs_mentioned **a_header;
  16886. +      int in_mem;
  16887. + {
  16888. +   register char *fmt;
  16889. +   register int i;
  16890. +   register enum rtx_code code;
  16891. +   struct regs_mentioned *one_reg;
  16892. +   code = GET_CODE (pat);
  16893. +   switch (code)
  16894. +     {
  16895. +     case REG:
  16896. +       if (REGNO (pat) < FIRST_PSEUDO_REGISTER)
  16897. +     {
  16898. +       return;
  16899. +     }
  16900. +       one_reg = (struct regs_mentioned *)
  16901. +     obstack_alloc (&momentary_obstack, sizeof (struct regs_mentioned));
  16902. +       one_reg->reg = pat;
  16903. +       one_reg->in_mem = in_mem;
  16904. +       one_reg->next = *a_header;
  16905. +       *a_header = one_reg;
  16906. +       return;
  16907. +       /* These codes have no constituent expressions
  16908. +      and are unique.  */
  16909. +     case SCRATCH:
  16910. +     case CC0:
  16911. +     case PC:
  16912. +     case QUEUED:
  16913. +     case CONST_INT:
  16914. +     case CONST_DOUBLE:
  16915. +     case SYMBOL_REF:
  16916. +     case CODE_LABEL:
  16917. +       return;
  16918. +     case MEM:
  16919. +       in_mem = 1;
  16920. +       break;
  16921. +     }
  16922. +   fmt = GET_RTX_FORMAT (code);
  16923. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  16924. +     {
  16925. +       if (fmt[i] == 'E')
  16926. +     {
  16927. +       register int j;
  16928. +       for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
  16929. +         find_regs_mentioned (XVECEXP (pat, i, j), a_header, in_mem);
  16930. +     }
  16931. +       else if (fmt[i] == 'e')
  16932. +     find_regs_mentioned (XEXP (pat, i), a_header, in_mem);
  16933. +     }
  16934. + }
  16935. + #ifdef REDUCE_INDEX
  16936. + /* Create givs which are only index terms of memory addresses.  */
  16937. + static int
  16938. + do_reduce_index (x, add_val)
  16939. +      rtx x, *add_val;
  16940. + {
  16941. +   rtx mem_address, sym_part, constint_part, save_add_val;
  16942. +   save_add_val = *add_val;
  16943. +   mem_address = XEXP (x, 0);
  16944. +   if (GET_CODE (mem_address) != PLUS)
  16945. +     {
  16946. +       return (0);
  16947. +     }
  16948. +   if (GET_CODE (XEXP (mem_address, 0)) == MULT)
  16949. +     {
  16950. +       if (!LEGITIMATE_INDEX_P (XEXP (mem_address, 0)) 
  16951. +       || GET_CODE (XEXP (mem_address, 1)) == REG    
  16952. +     )
  16953. +     { /* Will have index term anyway.  */
  16954. +       return (0);
  16955. +     }
  16956. +     }
  16957. +   else
  16958. +     {
  16959. +       return (0);
  16960. +     }
  16961. +   /* Strip from *(add_val) the non index part.  */
  16962. +   if (rtx_equal_p (*(add_val), XEXP (mem_address, 1)))
  16963. +     {
  16964. +       *(add_val) = const0_rtx;
  16965. +     }
  16966. +   else if (GET_CODE (*(add_val)) == CONST_INT)
  16967. +     {
  16968. +       if (GET_CODE (XEXP (mem_address, 1)) != CONST_INT)
  16969. +     {
  16970. +       return (0);
  16971. +     }
  16972. +       else
  16973. +     {
  16974. +       *(add_val) 
  16975. +         = gen_rtx (CONST_INT, 0,
  16976. +               INTVAL (*(add_val)) - INTVAL (XEXP (mem_address, 1)));
  16977. +     }
  16978. +     }
  16979. +   else if (GET_CODE (*(add_val)) == CONST)
  16980. +     {
  16981. +       if (!(GET_CODE (XEXP (*(add_val), 0)) == PLUS 
  16982. +         && GET_CODE (XEXP (XEXP (*(add_val), 0), 0)) == SYMBOL_REF 
  16983. +         && GET_CODE (XEXP (XEXP (*(add_val), 0), 1)) == CONST_INT)
  16984. +     )
  16985. +     {
  16986. +       return (0);
  16987. +     }
  16988. +       *(add_val) = XEXP (*(add_val), 0);
  16989. +       mem_address = XEXP (mem_address, 1);
  16990. +       if (GET_CODE (mem_address) == CONST)
  16991. +     {
  16992. +       mem_address = XEXP (mem_address, 0);
  16993. +     }
  16994. +       if (GET_CODE (mem_address) == PLUS)
  16995. +     {
  16996. +       sym_part = XEXP (mem_address, 0);
  16997. +       constint_part = XEXP (mem_address, 1);
  16998. +     }
  16999. +       else
  17000. +     {
  17001. +       sym_part = mem_address;
  17002. +       constint_part = const0_rtx;
  17003. +     }
  17004. +       if (!rtx_equal_p (XEXP (*(add_val), 0), sym_part))
  17005. +     {
  17006. +       *(add_val) = save_add_val;
  17007. +       return (0);
  17008. +     }
  17009. +       else
  17010. +     {
  17011. +       *(add_val) = XEXP (*(add_val), 1);
  17012. +       *(add_val) 
  17013. +         = gen_rtx (CONST_INT, 0, INTVAL (*(add_val)) - INTVAL (constint_part));
  17014. +     }
  17015. +     }
  17016. +   else
  17017. +     {
  17018. +       return (0);
  17019. +     }
  17020. +   return (1);
  17021. + }
  17022. + #endif
  17023. + struct regopt_info
  17024. + {
  17025. +   rtx insn_set;        /* The insn that loads the current value in the register */
  17026. +   rtx corresp_mem;    /* The memory that contains the same value as the register */
  17027. +   rtx reg;         /* The register */
  17028. +   char replace_reg;    /* If 1 replace reg with corresp_mem (for stack regs)
  17029. +                otherwise replace corresp_mem with reg */
  17030. +   char do_replace;    /* If 1 then this is a stack reg that has already
  17031. +                been used in this extended basic block -
  17032. +                try to replace susequent uses with this regs
  17033. +                corresponding mem */
  17034. + };
  17035. + static struct regopt_info *rinfo;
  17036. + struct undo
  17037. + {
  17038. +   rtx *where;
  17039. +   rtx old_contents;
  17040. +   int is_int;
  17041. + };
  17042. + #define MAX_UNDO 50
  17043. + struct undobuf
  17044. + {
  17045. +   int num_undo;
  17046. +   char *storage;
  17047. +   struct undo undo[MAX_UNDO];
  17048. +   rtx other_insn;
  17049. + };
  17050. + static struct undobuf undobuf;
  17051. + #define LOOP_SUBST(WHERE, NEWVAL)  \
  17052. +  do { if (undobuf.num_undo < MAX_UNDO)                    \
  17053. +     {                                \
  17054. +       undobuf.undo[undobuf.num_undo].where = WHERE;            \
  17055. +       undobuf.undo[undobuf.num_undo].old_contents = *WHERE;        \
  17056. +       undobuf.undo[undobuf.num_undo].is_int = 0;            \
  17057. +       *WHERE = NEWVAL;                        \
  17058. +       undobuf.num_undo++;                        \
  17059. +     }                                \
  17060. +     } while (0)
  17061. + static int mem_max_reg_num;
  17062. + #define SYMREF_PLUS_REG(insn)                        \
  17063. +      (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS &&            \
  17064. +      GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG &&         \
  17065. +      GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == SYMBOL_REF)
  17066. + /*  Try to replace a register use with the value that sets that the
  17067. +     register.  This is done for the following cases:
  17068. +     1) regx <- regy ashift const_int
  17069. +     2) regx <- symbol_ref + regy
  17070. +     3) regx <- (regy * const_int) + const_int
  17071. +     If only_symref_plus_reg==1 then regx is replaced only if it
  17072. +     used as a base or index register and is of type 2)
  17073. +     otherwise it is always replaced.  
  17074. +     Calling use_regs_source with only_symref_plus_reg==0 on a loop
  17075. +     before strength reduction causes strength reduction to better handle
  17076. +     mem givs.  
  17077. +     Calling use_regs_source with only_symref_plus_reg==1 at the end of
  17078. +     loop optimization will do the replacement even if combine would not.  
  17079. +     also if only_symref_plus_reg==1 and if we have
  17080. +     1) mem1 <- regx
  17081. +     then attempt to replace susequent uses of mem1 with regx
  17082. + */
  17083. + static
  17084. + void 
  17085. + use_regs_source (start, end, only_symref_plus_reg)
  17086. +      rtx start, end;
  17087. +      int only_symref_plus_reg;
  17088. + {
  17089. +   rtx insn, src, new_src, dest, tinsn, tmp_rtx;
  17090. +   struct regs_mentioned *header, *a_reg_used;
  17091. +   int recog_ok, i, insn_code_num, nested;
  17092. +   char *storage1, *storage2;
  17093. +   int cur_max_reg = max_reg_num () + 1;
  17094. +   mem_max_reg_num = cur_max_reg;
  17095. +   undobuf.num_undo = 0;
  17096. +   rinfo 
  17097. +     = (struct regopt_info *) alloca (cur_max_reg * sizeof (struct regopt_info));
  17098. +   bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
  17099. +   nested = 0;
  17100. +   insn = NEXT_INSN (start);
  17101. +   while (insn != end)
  17102. +     {
  17103. +       switch (GET_CODE (insn))
  17104. +     {
  17105. +     case NOTE:
  17106. +       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG 
  17107. +           && only_symref_plus_reg)
  17108. +         {
  17109. +           nested++;
  17110. +           bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
  17111. +         }
  17112. +       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END 
  17113. +           && only_symref_plus_reg)
  17114. +         {
  17115. +           nested--;
  17116. +           bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
  17117. +         }
  17118. +       break;
  17119. +     case JUMP_INSN:
  17120. +       if (nested == 0 || !only_symref_plus_reg)
  17121. +         {
  17122. +           if (SET_DEST (PATTERN (insn)) == pc_rtx
  17123. +           && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF)
  17124. +         {
  17125. +           bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
  17126. +         }
  17127. +           else if (!only_symref_plus_reg)
  17128. +         {
  17129. +           for (i = 0; i < cur_max_reg; i++)
  17130. +             {
  17131. +               rinfo[i].corresp_mem = NULL;
  17132. +             }
  17133. +         }
  17134. +         }
  17135. +       break;
  17136. +     case CALL_INSN:
  17137. +       if (nested == 0 || !only_symref_plus_reg)
  17138. +         {
  17139. +           bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
  17140. +         }
  17141. +       break;
  17142. +     case CODE_LABEL:
  17143. +     case BARRIER:
  17144. +       if (nested == 0 || !only_symref_plus_reg)
  17145. +         {
  17146. +           /* Forget everything */
  17147. +           bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
  17148. +         }
  17149. +       break;
  17150. +     case INSN:
  17151. +       if (!(nested == 0 || !only_symref_plus_reg))
  17152. +         break;
  17153. +           if (GET_CODE (PATTERN (insn)) == CLOBBER)
  17154. +             {
  17155. +               dest = SET_DEST (PATTERN (insn));
  17156. +           if (GET_CODE (dest) == REG)
  17157. +         {
  17158. +           rinfo[ REGNO (dest)].insn_set = NULL;
  17159. +           for (i = 0; i < cur_max_reg; i++)
  17160. +             {
  17161. +               if (rinfo[i].insn_set
  17162. +               && reg_overlap_mentioned_p (dest, 
  17163. +                     SET_SRC (PATTERN (rinfo[i].insn_set)))
  17164. +             )
  17165. +             { /* current value of reg dest overwritten */
  17166. +               rinfo[i].insn_set = NULL;
  17167. +                   if (rinfo[i].corresp_mem 
  17168. +                       && reg_overlap_mentioned_p (dest, 
  17169. +                            rinfo[i].corresp_mem))
  17170. +                 { /* Not the same memory address anymore.  */
  17171. +                   rinfo[i].corresp_mem = NULL;
  17172. +                 }
  17173. +             }
  17174. +             }
  17175. +         }
  17176. +           else if (GET_CODE (dest) == MEM && !only_symref_plus_reg 
  17177. +                && flag_replace_mem)
  17178. +         {
  17179. +           for (i = 0; i < cur_max_reg; i++)
  17180. +             {
  17181. +               if (rinfo[i].corresp_mem 
  17182. +               && true_dependence (dest, rinfo[i].corresp_mem))
  17183. +             { /* Memory address maybe overwritten.  */
  17184. +               rinfo[i].corresp_mem = NULL;
  17185. +             }
  17186. +             }
  17187. +         }
  17188. +             } else if (GET_CODE (PATTERN (insn)) == PARALLEL)
  17189. +         {
  17190. +                 dest = SET_DEST (PATTERN (insn));
  17191. +           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
  17192. +         {
  17193. +           rtx cur_rtx;
  17194. +           cur_rtx = XVECEXP (PATTERN (insn), 0, i);
  17195. +           if ((GET_CODE (cur_rtx) == SET || GET_CODE (cur_rtx) == CLOBBER)
  17196. +               && GET_CODE (SET_DEST (cur_rtx)) == REG)
  17197. +             {
  17198. +               rinfo[ REGNO (SET_DEST (cur_rtx))].insn_set = NULL;
  17199. +               for (i = 0; i < cur_max_reg; i++)
  17200. +                 {
  17201. +                   if (rinfo[i].insn_set
  17202. +                   && reg_overlap_mentioned_p (SET_DEST (cur_rtx), 
  17203. +                          SET_SRC (PATTERN (rinfo[i].insn_set)))
  17204. +                 )
  17205. +                 { /* Current value of reg dest overwritten */
  17206. +                   rinfo[i].insn_set = NULL;
  17207. +                 }
  17208. +                   if (rinfo[i].corresp_mem 
  17209. +                       && reg_overlap_mentioned_p (SET_DEST (cur_rtx), 
  17210. +                            rinfo[i].corresp_mem))
  17211. +                 { /* Not the same memory address anymore.  */
  17212. +                   rinfo[i].corresp_mem = NULL;
  17213. +                 }
  17214. +                 }
  17215. +             }
  17216. +               else if ((GET_CODE (cur_rtx) == SET || GET_CODE (cur_rtx) == CLOBBER)
  17217. +                   && GET_CODE (SET_DEST (cur_rtx)) == MEM
  17218. +                       && GET_CODE (dest) == MEM && !only_symref_plus_reg 
  17219. +                   && flag_replace_mem)
  17220. +             {
  17221. +               dest = SET_DEST (cur_rtx);
  17222. +               for (i = 0; i < cur_max_reg; i++)
  17223. +                 {
  17224. +                   if (rinfo[i].corresp_mem 
  17225. +                   && true_dependence (dest, rinfo[i].corresp_mem))
  17226. +                 { /* Memory address maybe overwritten.  */
  17227. +                   rinfo[i].corresp_mem = NULL;
  17228. +                 }
  17229. +                 }
  17230. +             }
  17231. +           else if (!(GET_CODE (cur_rtx) == SET  
  17232. +                || GET_CODE (cur_rtx) == CLOBBER
  17233. +                || GET_CODE (cur_rtx) == USE))
  17234. +                 bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
  17235. +         }
  17236. +         }
  17237. +       else if (GET_CODE (PATTERN (insn)) == SET)
  17238. +         {
  17239. +           dest = SET_DEST (PATTERN (insn));
  17240. +           if (GET_CODE (SET_SRC (PATTERN (insn))) != REG)
  17241. +         {
  17242. +           header = NULL;
  17243. +           storage2 = (char *) obstack_alloc (&momentary_obstack, 0);
  17244. +           find_regs_mentioned (SET_SRC (PATTERN (insn)), &header, 0);
  17245. +           a_reg_used = header;
  17246. +           while (a_reg_used)
  17247. +             {
  17248. +               undobuf.num_undo = 0;
  17249. +               undobuf.storage = (char *) oballoc (0);
  17250. +               if (((a_reg_used->in_mem || !only_symref_plus_reg) 
  17251. +                && rinfo[REGNO (a_reg_used->reg)].insn_set 
  17252. +                && rinfo[REGNO (a_reg_used->reg)].replace_reg == 0 
  17253. +                && (!only_symref_plus_reg 
  17254. +                    || SYMREF_PLUS_REG (rinfo[REGNO (a_reg_used->reg)].insn_set))) 
  17255. +               || (rinfo[REGNO (a_reg_used->reg)].corresp_mem 
  17256. +                && rinfo[REGNO (a_reg_used->reg)].insn_set 
  17257. +                && rinfo[REGNO (a_reg_used->reg)].replace_reg == 1 
  17258. +                && rinfo[REGNO (a_reg_used->reg)].do_replace == 1 
  17259. + #ifdef STACK_REGS
  17260. + #ifdef IS_STACK_MODE
  17261. +               && !((GET_CODE (SET_SRC (PATTERN (insn))) == FLOAT_EXTEND 
  17262. +               || GET_CODE (SET_SRC (PATTERN (insn))) == FLOAT_TRUNCATE)
  17263. +               && (IS_STACK_MODE (SFmode) || IS_STACK_MODE (DFmode)))
  17264. +                
  17265. + #endif
  17266. + #endif
  17267. +                && !only_symref_plus_reg && flag_replace_stack_mem)
  17268. +             )
  17269. +             { /* Try to replace the register with it's current
  17270. +                       value.  */
  17271. +               replace_reg (SET_SRC (PATTERN (insn)),
  17272. +                        &SET_SRC (PATTERN (insn)),
  17273. +                        a_reg_used->reg,
  17274. +                        &(rinfo[REGNO (a_reg_used->reg)]));
  17275. +               if ((insn_code_num = recog (PATTERN (insn), insn, 0)) < 0)
  17276. +                 {
  17277. +                   recog_ok = 0;
  17278. +                   try_to_make_good (SET_SRC (PATTERN (insn)));
  17279. +                 }
  17280. +               else
  17281. +                 {
  17282. +                   recog_ok = 1;
  17283. +                 }
  17284. +               if (recog_ok 
  17285. +                   || (insn_code_num = recog (PATTERN (insn), insn, 0)) >= 0)
  17286. +                 {
  17287. +                   INSN_CODE (insn) = insn_code_num;
  17288. +                   /* canonicalize */
  17289. +                   if (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS 
  17290. +                   && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == MULT 
  17291. +                   && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG)
  17292. +                 {
  17293. +                   tmp_rtx = XEXP (SET_SRC (PATTERN (insn)), 0);
  17294. +                   XEXP (SET_SRC (PATTERN (insn)), 0) 
  17295. +                     = XEXP (SET_SRC (PATTERN (insn)), 1);
  17296. +                   XEXP (SET_SRC (PATTERN (insn)), 1) = tmp_rtx;
  17297. +                 }
  17298. +                 }
  17299. +               else
  17300. +                 {
  17301. +                   loop_undo_all ();
  17302. +                 }
  17303. +             }
  17304. + #ifdef STACK_REGS
  17305. + #ifdef IS_STACK_MODE
  17306. +               if (IS_STACK_MODE (GET_MODE (a_reg_used->reg)))
  17307. +             {
  17308. +               rinfo[REGNO (a_reg_used->reg)].do_replace = 1;
  17309. +             }
  17310. + #endif
  17311. + #endif
  17312. +               a_reg_used = a_reg_used->next;
  17313. +             }
  17314. +           if (header != NULL)
  17315. +             {
  17316. +               obstack_free (&momentary_obstack, storage2);
  17317. +             }
  17318. +           if (!only_symref_plus_reg && flag_replace_mem)
  17319. +             replace_mems (insn, SET_SRC (PATTERN (insn)));
  17320. +         }
  17321. +           src = SET_SRC (PATTERN (insn));
  17322. +           if (GET_CODE (dest) != REG)
  17323. +         {
  17324. +           header = NULL;
  17325. +           storage2 = (char *) obstack_alloc (&momentary_obstack, 0);
  17326. +           find_regs_mentioned (SET_DEST (PATTERN (insn)), &header, 0);
  17327. +           a_reg_used = header;
  17328. +           while (a_reg_used)
  17329. +             {
  17330. +               undobuf.num_undo = 0;
  17331. +               undobuf.storage = (char *) oballoc (0);
  17332. +               if (a_reg_used->in_mem 
  17333. +               && rinfo[REGNO (a_reg_used->reg)].insn_set 
  17334. +               && (!only_symref_plus_reg 
  17335. +                || SYMREF_PLUS_REG (rinfo[REGNO (a_reg_used->reg)].insn_set))
  17336. +             )
  17337. +             { /* Try to replace the register with it's current
  17338. +                      value.  */
  17339. +               replace_reg (SET_DEST (PATTERN (insn)),
  17340. +                        &SET_DEST (PATTERN (insn)),
  17341. +                        a_reg_used->reg,
  17342. +                        &(rinfo[REGNO (a_reg_used->reg)]));
  17343. +               if (recog (PATTERN (insn), insn, 0) < 0)
  17344. +                 {
  17345. +                   recog_ok = 0;
  17346. +                   try_to_make_good (SET_DEST (PATTERN (insn)));
  17347. +                 }
  17348. +               else
  17349. +                 {
  17350. +                   recog_ok = 1;
  17351. +                 }
  17352. +               if (recog_ok 
  17353. +                   || recog (PATTERN (insn), insn, 0) >= 0)
  17354. +                 {
  17355. +                   ;
  17356. +                 }
  17357. +               else
  17358. +                 {
  17359. +                   loop_undo_all ();
  17360. +                 }
  17361. +             }
  17362. +               a_reg_used = a_reg_used->next;
  17363. +             }
  17364. +           if (header != NULL)
  17365. +             {
  17366. +               obstack_free (&momentary_obstack, storage2);
  17367. +             }
  17368. +           if (!only_symref_plus_reg 
  17369. +               && GET_CODE (src) == REG && GET_CODE (dest) == MEM 
  17370. +               && !MEM_VOLATILE_P (dest) 
  17371. +               && GET_CODE (XEXP (dest, 0)) != PRE_DEC 
  17372. +               && GET_CODE (XEXP (dest, 0)) != PRE_INC
  17373. + #ifdef STACK_REGS
  17374. + #ifdef IS_STACK_MODE
  17375. +               && !(IS_STACK_MODE (GET_MODE (src)))
  17376. + #endif
  17377. + #endif
  17378. +             )
  17379. +             {
  17380. +               rinfo[REGNO (src)].corresp_mem = dest;
  17381. +               rinfo[REGNO (src)].reg = src;
  17382. +               rinfo[REGNO (src)].replace_reg = 0;
  17383. +             }
  17384. +         }
  17385. +           if (GET_CODE (dest) == MEM && !only_symref_plus_reg 
  17386. +           && flag_replace_mem)
  17387. +         {
  17388. +           for (i = 0; i < cur_max_reg; i++)
  17389. +             {
  17390. +               if (rinfo[i].corresp_mem && !(GET_CODE (src) == REG && i == REGNO (src)) 
  17391. +               && true_dependence (dest, rinfo[i].corresp_mem))
  17392. +             { /* Memory address maybe overwritten.  */
  17393. +               rinfo[i].corresp_mem = NULL;
  17394. +             }
  17395. +             }
  17396. +         }
  17397. +           if (GET_CODE (dest) == REG)
  17398. +         {
  17399. +           for (i = 0; i < cur_max_reg; i++)
  17400. +             {
  17401. +               if (rinfo[i].insn_set 
  17402. +               && reg_overlap_mentioned_p (dest, SET_SRC (PATTERN (rinfo[i].insn_set)))
  17403. +             )
  17404. +             { /* Current value of reg dest overwritten.  */
  17405. +               rinfo[i].insn_set = NULL;
  17406. +             }
  17407. +               if (rinfo[i].corresp_mem 
  17408. +                   && reg_overlap_mentioned_p (dest, rinfo[i].corresp_mem))
  17409. +             { /* Not the same memory address anymore.  */
  17410. +               rinfo[i].corresp_mem = NULL;
  17411. +             }
  17412. +             }
  17413. +           rinfo[REGNO (dest)].corresp_mem = NULL;
  17414. +           if (reg_overlap_mentioned_p (dest, SET_SRC (PATTERN (insn))))
  17415. +             {
  17416. +               rinfo[REGNO (dest)].insn_set = NULL;
  17417. +             }
  17418. +           else
  17419. +             {
  17420. +               if ((GET_CODE (SET_SRC (PATTERN (insn))) == ASHIFT 
  17421. +                    && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG 
  17422. +                && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT) 
  17423. +                || (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS 
  17424. +                        && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG 
  17425. +                    && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == SYMBOL_REF) 
  17426. +                || (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS 
  17427. +                    && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == MULT 
  17428. +                    && GET_CODE (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0)) == REG 
  17429. +                    && GET_CODE (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 1)) == CONST_INT 
  17430. +                    && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
  17431. +             )
  17432. +             { /* These are the patterns of interest.  */
  17433. +               rinfo[REGNO (dest)].insn_set = insn;
  17434. +             }
  17435. +               else
  17436. +             {
  17437. +               rinfo[REGNO (dest)].insn_set = NULL;
  17438. +             }
  17439. + #ifdef STACK_REGS
  17440. + #ifdef IS_STACK_MODE
  17441. +               if (IS_STACK_MODE (GET_MODE (dest)) 
  17442. +                   && ((GET_CODE (src) == MEM 
  17443. +                        && !MEM_VOLATILE_P (src)) 
  17444. +                        || ((IS_STACK_MODE (SFmode) || IS_STACK_MODE (DFmode)) 
  17445. +                             && (GET_CODE (src) == FLOAT_EXTEND 
  17446. +                                 || GET_CODE (src) == FLOAT_TRUNCATE) 
  17447. +                   && GET_CODE (XEXP (src, 0)) == MEM 
  17448. +                   && !MEM_VOLATILE_P (XEXP (src, 0))))
  17449. +                   && flag_replace_stack_mem)
  17450. +             {
  17451. +               rinfo[REGNO (dest)].corresp_mem = src;
  17452. +               rinfo[REGNO (dest)].reg = dest;
  17453. +               rinfo[REGNO (dest)].insn_set = insn;
  17454. +               rinfo[REGNO (dest)].replace_reg = 1;
  17455. +               rinfo[REGNO (dest)].do_replace = 0;
  17456. +             }
  17457. + #endif
  17458. + #endif
  17459. +             }
  17460. +         }
  17461. +         }
  17462. +       else if (GET_CODE (PATTERN (insn)) != USE)
  17463. +         {
  17464. +           bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
  17465. +         }
  17466. +       break;
  17467. +     default:
  17468. +       bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
  17469. +       break;
  17470. +     }
  17471. +       insn = NEXT_INSN (insn);
  17472. +     }
  17473. + }
  17474. + void
  17475. + loop_undo_all ()
  17476. + {
  17477. +   register int i;
  17478. +   if (undobuf.num_undo > MAX_UNDO)
  17479. +     undobuf.num_undo = MAX_UNDO;
  17480. +   for (i = undobuf.num_undo - 1; i >= 0; i--)
  17481. +     *undobuf.undo[i].where = undobuf.undo[i].old_contents;
  17482. +   obfree (undobuf.storage);
  17483. +   undobuf.num_undo = 0;
  17484. + }
  17485. + /* Replace in pat of insn each MEM with a corresponding reg if one exists.  */
  17486. + static
  17487. + rtx 
  17488. + replace_mems (insn, pat)
  17489. +      rtx insn, pat;
  17490. + {
  17491. +   register RTX_CODE code = GET_CODE (pat);
  17492. +   register int i, j;
  17493. +   register char *fmt;
  17494. +   switch (code)
  17495. +     {
  17496. +     case HIGH:
  17497. +     case CONST_INT:
  17498. +     case CONST:
  17499. +     case CONST_DOUBLE:
  17500. +     case SYMBOL_REF:
  17501. +     case LABEL_REF:
  17502. +     case PC:
  17503. +     case CC0:
  17504. +     case REG:
  17505. +       return pat;
  17506. +     }
  17507. +   if (GET_CODE (pat) == MEM)
  17508. +     {
  17509. +       for (i = 0; i < mem_max_reg_num; i++)
  17510. +     {
  17511. +       if (rinfo[i].corresp_mem && rinfo[i].replace_reg == 0 
  17512. +           && rtx_equal_p (rinfo[i].corresp_mem, pat))
  17513. +         {
  17514. +           return (rinfo[i].reg);
  17515. +         }
  17516. +     }
  17517. +     }
  17518. +   fmt = GET_RTX_FORMAT (code);
  17519. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  17520. +     if (fmt[i] == 'e')
  17521. +       XEXP (pat, i) = replace_mems (insn, XEXP (pat, i));
  17522. +     else if (fmt[i] == 'E' || fmt[i] == 'V')
  17523. +       {
  17524. +     for (j = 0; j < XVECLEN (pat, i); j++)
  17525. +       XVECEXP (pat, i, j) 
  17526. +         = replace_mems (insn, XVECEXP (pat, i, j));
  17527. +       }
  17528. +   return pat;
  17529. + }
  17530. + /* Replace in orig each occurrence of reg_rplc with the value
  17531. +    described by *rptr.  The location in orig of reg_rplc is where.  
  17532. + */
  17533. + static void
  17534. + replace_reg (orig, where, reg_rplc, rptr)
  17535. +      register rtx orig, reg_rplc;
  17536. +      rtx *where;
  17537. +      struct regopt_info *rptr;
  17538. + {
  17539. +   rtx non_biv_operand, ret_rtx;
  17540. +   register int i, j;
  17541. +   register RTX_CODE code;
  17542. +   register char *fmt;
  17543. +   code = GET_CODE (orig);
  17544. +   switch (code)
  17545. +     {
  17546. +     case REG:
  17547. +       if (rtx_equal_p (orig, reg_rplc))
  17548. +     {
  17549. +       if (GET_CODE (SET_SRC (PATTERN (rptr->insn_set))) == ASHIFT 
  17550. +           && GET_CODE (XEXP (SET_SRC (PATTERN (rptr->insn_set)), 1)) == CONST_INT
  17551. +         )
  17552. +         {
  17553. +           LOOP_SUBST (where,
  17554. +           (gen_rtx (MULT, GET_MODE (SET_SRC (PATTERN (rptr->insn_set))),
  17555. +             XEXP (SET_SRC (PATTERN (rptr->insn_set)), 0),
  17556. +             gen_rtx (CONST_INT, 0,
  17557. +                  two_to_power (INTVAL (XEXP (SET_SRC (PATTERN (rptr->insn_set)), 1)))))));
  17558. +         }
  17559. +       else
  17560. +         {
  17561. +           LOOP_SUBST (where, (SET_SRC (PATTERN (rptr->insn_set))));
  17562. +         }
  17563. +     }
  17564. +       break;
  17565. +     case QUEUED:
  17566. +     case CONST_INT:
  17567. +     case CONST_DOUBLE:
  17568. +     case SYMBOL_REF:
  17569. +     case CODE_LABEL:
  17570. +     case PC:
  17571. +     case CC0:
  17572. +       return;
  17573. +     }
  17574. +   fmt = GET_RTX_FORMAT (code);
  17575. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  17576. +     if (fmt[i] == 'e')
  17577. +       replace_reg (XEXP (orig, i), &XEXP (orig, i), reg_rplc, rptr);
  17578. +     else if (fmt[i] == 'E' || fmt[i] == 'V')
  17579. +       {
  17580. +     for (j = 0; j < XVECLEN (orig, i); j++)
  17581. +       replace_reg (XVECEXP (orig, i, j), &XVECEXP (orig, i, j), reg_rplc, rptr);
  17582. +       }
  17583. + }
  17584. + static int
  17585. + two_to_power (x)
  17586. +      int x;
  17587. + {
  17588. +   int retval, i;
  17589. +   retval = 1;
  17590. +   for (i = 0; i < x; i++)
  17591. +     retval *= 2;
  17592. +   return (retval);
  17593. + }
  17594. + /* Return 1 iff insn p jumps backward to a label that is located
  17595. +    between loop_start and p,
  17596. +    if strict==1 we also require that any jumps between the target label and
  17597. +    p jump to labels that are between the target label and p.  */
  17598. + static int
  17599. + jumps_back_in_loop (p, loop_start, use1, strict)
  17600. +      rtx p, loop_start;
  17601. +      int use1;        /* If 1 then we require each label within to be accessed only once */
  17602. +      int strict;
  17603. + {
  17604. +   rtx insn, target, last_jump_found;
  17605. +   int jumps_found, labels_found;
  17606. +   if (!flag_jump_back)
  17607. +     return (0);
  17608. +   target = JUMP_LABEL (p);
  17609. +   insn = PREV_INSN (p);
  17610. +   jumps_found = 0;
  17611. +   labels_found = 0;
  17612. +   while (insn != target && insn != loop_start)
  17613. +     {
  17614. +       if (GET_CODE (insn) == JUMP_INSN)
  17615. +     {
  17616. +       jumps_found++;
  17617. +     }
  17618. +       else if (GET_CODE (insn) == CODE_LABEL)
  17619. +     {
  17620. +       if (use1 && LABEL_NUSES (insn) != 1)
  17621. +         {
  17622. +           return (0);
  17623. +         }
  17624. +       labels_found++;
  17625. +     }
  17626. +       insn = PREV_INSN (insn);
  17627. +     }
  17628. +   if (insn != target)
  17629. +     {
  17630. +       return (0);
  17631. +     }
  17632. +   else
  17633. +     {
  17634. +       if (use1 && jumps_found != labels_found)
  17635. +     {
  17636. +       return (0);
  17637. +     }
  17638. +       if (jumps_found == 0 || strict == 0)
  17639. +     {
  17640. +       return (1);
  17641. +     }
  17642. +       else
  17643. +     { /* Must check each jump to see that it jumps to label
  17644. +          between target and p.  */
  17645. +       last_jump_found = target;
  17646. +       while (jumps_found)
  17647. +         {
  17648. +           /* Find the next jump.  */
  17649. +           insn = NEXT_INSN (last_jump_found);
  17650. +           while (GET_CODE (insn) != JUMP_INSN)
  17651. +         {
  17652. +           insn = NEXT_INSN (insn);
  17653. +         }
  17654. +           last_jump_found = insn;
  17655. +           /* Now find the target. */
  17656. +           while (insn != p && insn != JUMP_LABEL (last_jump_found))
  17657. +         { /* Search forward.  */
  17658. +           insn = NEXT_INSN (insn);
  17659. +         }
  17660. +           if (insn == JUMP_LABEL (last_jump_found) 
  17661. +           && (!use1 || LABEL_NUSES (JUMP_LABEL (last_jump_found)) == 1)
  17662. +         )
  17663. +         {
  17664. +           jumps_found--;
  17665. +         }
  17666. +           else
  17667. +         {
  17668. +           while (insn != loop_start && insn != JUMP_LABEL (last_jump_found))
  17669. +             { /* Search backwards. */
  17670. +               insn = PREV_INSN (insn);
  17671. +             }
  17672. +           if (insn == JUMP_LABEL (last_jump_found) 
  17673. +               && (!use1 || LABEL_NUSES (JUMP_LABEL (last_jump_found)) == 1)
  17674. +             )
  17675. +             {
  17676. +               jumps_found--;
  17677. +             }
  17678. +           else
  17679. +             {
  17680. +               break;
  17681. +             }
  17682. +         }
  17683. +         }
  17684. +       return (jumps_found == 0);
  17685. +     }
  17686. +     }
  17687. + }
  17688. + struct propogate_cand
  17689. + {
  17690. +   rtx srcpat;
  17691. +   rtx add_reg0;
  17692. +   rtx add_reg1;
  17693. +   rtx mul_reg;
  17694. +   rtx reg;
  17695. +   int mul_val;
  17696. +   char cand_type;
  17697. + };
  17698. + struct unroll_combine_cand
  17699. + {
  17700. +   rtx reg;
  17701. +   struct unroll_combine_cand *next;
  17702. + };
  17703. + #define COPY 1
  17704. + #define GIV 2
  17705. + /* Try to propogate copies into loop as follows:
  17706. +    If before the loop we have
  17707. +    regx <- regy
  17708. +    and in the loop regx is only used, then replace each use of regx
  17709. +    in the loop with regy
  17710. + */
  17711. + static
  17712. + loop_copy_propogate (loop_start, loop_end)
  17713. +      rtx loop_start, loop_end;
  17714. + {
  17715. +   struct propogate_cand *copy_candidates, *possible_giv_candidate;
  17716. +   char *regs_set, dummyc;
  17717. +   rtx insn, loop_label, loop_jump, dest, src, *split_giv_src;
  17718. +   int num_copy_candidates, num_giv_candidates,
  17719. +     stop_looking, cur_max_regnum, i, dummyi, num_unroll_candidates;
  17720. +   struct unroll_combine_cand **unroll_cands, *an_unroll_cand;
  17721. +   cur_max_regnum = max_reg_num () + 1;
  17722. +   if (loop_dump_stream)
  17723. +     {
  17724. +       fprintf (loop_dump_stream, "copy prop from %d to %d\n",
  17725. +            INSN_UID (loop_start), INSN_UID (loop_end));
  17726. +     }
  17727. +   copy_candidates = (struct propogate_cand *)
  17728. +     alloca (cur_max_regnum * sizeof (struct propogate_cand));
  17729. +   bzero (copy_candidates, (cur_max_regnum * sizeof (struct propogate_cand)));
  17730. +   regs_set = (char *) alloca (cur_max_regnum);
  17731. +   bzero (regs_set, cur_max_regnum);
  17732. +   n_times_set = (short *) alloca (cur_max_regnum * sizeof (short));
  17733. +   bzero (n_times_set, cur_max_regnum * sizeof (short));
  17734. +   may_not_optimize = (char *) alloca (cur_max_regnum);    /* not used */
  17735. +   if (flag_unroll_loops)
  17736. +     {
  17737. +       unroll_cands 
  17738. +     = (struct unroll_combine_cand **)
  17739. +     alloca (cur_max_regnum * sizeof (struct unroll_combine_cand *));
  17740. +       bzero (unroll_cands, cur_max_regnum * sizeof (struct unroll_combine_cand *));
  17741. +       split_giv_src = (rtx *) alloca (cur_max_regnum * sizeof (rtx));
  17742. +       bzero (split_giv_src, cur_max_regnum * sizeof (rtx));
  17743. +     }
  17744. +   /* First check that the label that is the start of the loop
  17745. +      is only jumped to from within the loop - if not return
  17746. +   */
  17747. +   insn = loop_start;
  17748. +   while (insn && GET_CODE (insn) != CODE_LABEL)
  17749. +     {
  17750. +       insn = NEXT_INSN (insn);
  17751. +     }
  17752. +   loop_label = insn;
  17753. +   insn = loop_end;
  17754. +   while (insn && GET_CODE (insn) != JUMP_INSN)
  17755. +     {
  17756. +       insn = PREV_INSN (insn);
  17757. +     }
  17758. +   loop_jump = insn;
  17759. +   if (!loop_label || !loop_jump 
  17760. +       || (JUMP_LABEL (loop_jump) != loop_label) 
  17761. +       || (LABEL_NUSES (JUMP_LABEL (loop_jump)) != 1)
  17762. +     )
  17763. +     {
  17764. +       return;
  17765. +     }
  17766. +   /* Compute n_times_set */
  17767. +   count_loop_regs_set (loop_start, loop_end, may_not_optimize, NULL,
  17768. +                &dummyi, cur_max_regnum);
  17769. +   /* Look backwards from loop_start until a label barier or
  17770. +      uncoditional jump is reached,
  17771. +      searching for insns of the form regx <- regy and regx
  17772. +      NOT set in loop  - these are candidates for copy propogation.  
  17773. +      Also search for registers that are set rega <- regb*C + regd
  17774. +      - rega is a candidate for inter loop giv combination.  
  17775. +   */
  17776. +   insn = loop_start;
  17777. +   num_copy_candidates = 0;
  17778. +   num_giv_candidates = 0;
  17779. +   num_unroll_candidates = 0;
  17780. +   stop_looking = 0;
  17781. +   possible_giv_candidate = NULL;
  17782. +   while (insn && !stop_looking)
  17783. +     {
  17784. +       switch (GET_CODE (insn))
  17785. +     {
  17786. +     case NOTE:
  17787. +       break;
  17788. +     case JUMP_INSN:
  17789. +       if (SET_DEST (PATTERN (insn)) == pc_rtx
  17790. +           && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF)
  17791. +         {
  17792. +           stop_looking = 1;
  17793. +         }
  17794. +       break;
  17795. +     case CODE_LABEL:
  17796. +     case BARRIER:
  17797. +       stop_looking = 1;
  17798. +       break;
  17799. +     case INSN:
  17800. +       if (GET_CODE (PATTERN (insn)) != SET)
  17801. +         {
  17802. +           stop_looking = 1;
  17803. +         }
  17804. +       else
  17805. +         {
  17806. +           dest = SET_DEST (PATTERN (insn));
  17807. +           src = SET_SRC (PATTERN (insn));
  17808. +           if (GET_CODE (dest) == REG)
  17809. +         {
  17810. +           if (flag_unroll_loops && dest != cc0_rtx 
  17811. +               && REGNO (dest) >= FIRST_PSEUDO_REGISTER 
  17812. +               && dest != pc_rtx && regs_set[REGNO (dest)] == 0 
  17813. +               && GET_CODE (src) == REG && regs_set[REGNO (src)] == 0
  17814. +               && REGNO (src) >= FIRST_PSEUDO_REGISTER )
  17815. +             { /* The dest may be a split giv which we want
  17816. +                          to combine */
  17817. +               if (split_giv_src[REGNO (dest)] == NULL)
  17818. +             {
  17819. +               split_giv_src[REGNO (dest)] = src;
  17820. +               an_unroll_cand 
  17821. +                 = (struct unroll_combine_cand *)
  17822. +                 alloca (sizeof (struct unroll_combine_cand));
  17823. +               an_unroll_cand->reg = dest;
  17824. +               an_unroll_cand->next = unroll_cands[REGNO (src)];
  17825. +               unroll_cands[REGNO (src)] = an_unroll_cand;
  17826. +               num_unroll_candidates++;
  17827. +             }
  17828. +               else
  17829. +             {
  17830. +               split_giv_src[REGNO (dest)] = (rtx) - 1;
  17831. +             }
  17832. +             }
  17833. +           if (dest != cc0_rtx && dest != pc_rtx 
  17834. +               && REGNO (dest) >= FIRST_PSEUDO_REGISTER 
  17835. +               && regs_set[REGNO (dest)] == 0)
  17836. +             {
  17837. +               if (GET_CODE (src) == REG 
  17838. +               && REGNO (src) >= FIRST_PSEUDO_REGISTER 
  17839. +               && n_times_set[REGNO (src)] == 0 
  17840. +               && regs_set[REGNO (src)] == 0)
  17841. +             {
  17842. +               if (n_times_set[REGNO (dest)] == 0)
  17843. +                 {
  17844. +                   num_copy_candidates++;
  17845. +                   copy_candidates[REGNO (dest)].srcpat = src;
  17846. +                   copy_candidates[REGNO (dest)].cand_type = COPY;
  17847. +                 }
  17848. +             }
  17849. +               else
  17850. +             {
  17851. +               if (GET_CODE (src) == PLUS 
  17852. +                   && GET_CODE (XEXP (src, 0)) == REG 
  17853. +                   && REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER 
  17854. +                   && GET_CODE (XEXP (src, 1)) == REG 
  17855. +                   && REGNO (XEXP (src, 1)) >= FIRST_PSEUDO_REGISTER 
  17856. +                   && regs_set[REGNO (XEXP (src, 0))] == 0 
  17857. +                   && regs_set[REGNO (XEXP (src, 1))] == 0 
  17858. +                   && n_times_set[REGNO (XEXP (src, 1))] == 0 
  17859. +                   && copy_candidates[REGNO (dest)].srcpat == NULL 
  17860. +                   && copy_candidates[REGNO (dest)].add_reg0 == NULL)
  17861. +                 {
  17862. +                   copy_candidates[REGNO (dest)].add_reg0 
  17863. +                 = XEXP (src, 0);
  17864. +                   copy_candidates[REGNO (dest)].add_reg1 
  17865. +                 = XEXP (src, 1);
  17866. +                   possible_giv_candidate 
  17867. +                 = ©_candidates[REGNO (dest)];
  17868. +                   possible_giv_candidate->reg = dest;
  17869. +                 }
  17870. +               else if (GET_CODE (src) == ASHIFT 
  17871. +                    && GET_CODE (XEXP (src, 0)) == REG 
  17872. +                    && GET_CODE (XEXP (src, 1)) == CONST_INT 
  17873. +                    && regs_set[REGNO (XEXP (src, 0))] == 0 
  17874. +                    && possible_giv_candidate 
  17875. +                    && possible_giv_candidate->mul_reg == NULL 
  17876. +                    && rtx_equal_p (dest, possible_giv_candidate->add_reg0)
  17877. +                 )
  17878. +                 {
  17879. +                   possible_giv_candidate->mul_reg = XEXP (src, 0);
  17880. +                   possible_giv_candidate->mul_val 
  17881. +                 = two_to_power (INTVAL (XEXP (src, 1)));
  17882. +                   possible_giv_candidate->cand_type = GIV;
  17883. +                   num_giv_candidates++;
  17884. +                 }
  17885. +             }
  17886. +             }
  17887. +           regs_set[REGNO (dest)] = 1;
  17888. +         }
  17889. +         }
  17890. +       break;
  17891. +     default:
  17892. +       stop_looking = 1;
  17893. +       break;
  17894. +     }
  17895. +       insn = PREV_INSN (insn);
  17896. +     }
  17897. +   if (num_copy_candidates != 0)
  17898. +     {
  17899. +       /* Now for each candidate do the replacement */
  17900. +       do_replace (loop_start, loop_end, copy_candidates);
  17901. +     }
  17902. +   if (num_unroll_candidates != 0)
  17903. +     {
  17904. +       try_unroll_propogation (loop_start, loop_end, unroll_cands, split_giv_src);
  17905. +     }
  17906. + }
  17907. + /*
  17908. +   Each occurence of a copy_candidate in an insn between loop_start
  17909. +   and loop_end is replaced by the corresponding register.  
  17910. + */
  17911. + static
  17912. + do_replace (loop_start, loop_end, copy_candidates)
  17913. +      rtx loop_start, loop_end;
  17914. +      struct propogate_cand *copy_candidates;
  17915. + {
  17916. +   rtx insn, subst_cands ();
  17917. +   for (insn = loop_start; insn != loop_end; insn = NEXT_INSN (insn))
  17918. +     {
  17919. +       if (GET_CODE (insn) == INSN)
  17920. +     {
  17921. +       subst_cands (insn, PATTERN (insn), copy_candidates);
  17922. +     }
  17923. +     }
  17924. + }
  17925. + /* Each register in pat which is a copy_candidate of type COPY is replaced with
  17926. +    it's copy from outside the loop.  
  17927. + */
  17928. + static
  17929. + rtx 
  17930. + subst_cands (insn, pat, copy_candidates)
  17931. +      rtx insn, pat;
  17932. +      struct propogate_cand *copy_candidates;
  17933. + {
  17934. +   register RTX_CODE code = GET_CODE (pat);
  17935. +   register int i, j;
  17936. +   register char *fmt;
  17937. +   switch (code)
  17938. +     {
  17939. +     case HIGH:
  17940. +     case CONST_INT:
  17941. +     case CONST:
  17942. +     case CONST_DOUBLE:
  17943. +     case SYMBOL_REF:
  17944. +     case LABEL_REF:
  17945. +     case PC:
  17946. +     case CC0:
  17947. +       return pat;
  17948. +     case REG:
  17949. +       {
  17950. +     register int regno = REGNO (pat);
  17951. +     if (copy_candidates[regno].srcpat 
  17952. +         && copy_candidates[regno].cand_type == COPY)
  17953. +       {
  17954. +         if (loop_dump_stream)
  17955. +           {
  17956. +         fprintf (loop_dump_stream, "replacing reg%d with reg%d in insn %d\n",
  17957. +              regno, REGNO (copy_candidates[regno].srcpat), INSN_UID (insn));
  17958. +           }
  17959. +         return (copy_candidates[regno].srcpat);
  17960. +       }
  17961. +       }
  17962. +       return pat;
  17963. +     }
  17964. +   fmt = GET_RTX_FORMAT (code);
  17965. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  17966. +     if (fmt[i] == 'e')
  17967. +       XEXP (pat, i) = subst_cands (insn, XEXP (pat, i), copy_candidates);
  17968. +     else if (fmt[i] == 'E' || fmt[i] == 'V')
  17969. +       {
  17970. +     for (j = 0; j < XVECLEN (pat, i); j++)
  17971. +       XVECEXP (pat, i, j) 
  17972. +         = subst_cands (insn, XVECEXP (pat, i, j), copy_candidates);
  17973. +       }
  17974. +   return pat;
  17975. + }
  17976. + struct reg_incs
  17977. + {
  17978. +   int inc_val;
  17979. +   char invalid;
  17980. + };
  17981. + /* Try to combine split givs from unrolling into one giv to decrease
  17982. +    register pressure and increase scheduling possiblities
  17983. + */
  17984. + static
  17985. + try_unroll_propogation (loop_start, loop_end, unroll_cands, split_giv_src)
  17986. +      rtx loop_start, loop_end;
  17987. +      struct unroll_combine_cand **unroll_cands;
  17988. +      rtx *split_giv_src;
  17989. + {
  17990. +   rtx insn, src, dest, ninsn, nsrc, ndest, unroll_subst_cands ();
  17991. +   struct reg_incs *reg_inc;
  17992. +   int i, cur_max_regnum, found;
  17993. +   if (loop_dump_stream)
  17994. +     {
  17995. +       fprintf (loop_dump_stream, " unroll propogate from %d to %d\n",
  17996. +            INSN_UID (loop_start), INSN_UID (loop_end));
  17997. +     }
  17998. +   cur_max_regnum = max_reg_num () + 1;
  17999. +   reg_inc 
  18000. +     = (struct reg_incs *) alloca (cur_max_regnum * (sizeof (struct reg_incs)));
  18001. +   bzero (reg_inc, cur_max_regnum * (sizeof (struct reg_incs)));
  18002. +   insn = NEXT_INSN (loop_start);
  18003. +   while (insn != loop_end)
  18004. +     {
  18005. +       switch (GET_CODE (insn))
  18006. +     {
  18007. +     case NOTE:
  18008. +       break;
  18009. +     case JUMP_INSN:
  18010. +     case CODE_LABEL:
  18011. +     case BARRIER:
  18012. +       unroll_consistancy_maintained (cur_max_regnum, unroll_cands,
  18013. +                      reg_inc, insn, split_giv_src);
  18014. +       /* forget everything */
  18015. +       bzero (reg_inc, cur_max_regnum * (sizeof (struct reg_incs)));
  18016. +       break;
  18017. +     case INSN:
  18018. +       if (GET_CODE (PATTERN (insn)) == PARALLEL)
  18019. +         {
  18020. +           return;
  18021. +         }
  18022. +       if (GET_CODE (PATTERN (insn)) != SET)
  18023. +         {
  18024. +           return;
  18025. +         }
  18026. +       dest = SET_DEST (PATTERN (insn));
  18027. +       if (GET_CODE (dest) == REG)
  18028. +         {
  18029. +           if (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS 
  18030. +           && rtx_equal_p (XEXP (SET_SRC (PATTERN (insn)), 0), dest) 
  18031. +           && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
  18032. +         { /* reg incremented by constatnt */
  18033. +           reg_inc[REGNO (dest)].inc_val 
  18034. +             += INTVAL (XEXP (SET_SRC (PATTERN (insn)), 1));
  18035. +         }
  18036. +           else
  18037. +         {
  18038. +           reg_inc[REGNO (dest)].invalid = 1;
  18039. +         }
  18040. +         }
  18041. +       break;
  18042. +     default:
  18043. +       return;
  18044. +       break;
  18045. +     }
  18046. +       insn = NEXT_INSN (insn);
  18047. +     }
  18048. +   insn = NEXT_INSN (loop_start);
  18049. +   /* Combine each valid unroll candidate */
  18050. +   for (insn = loop_start; insn != loop_end; insn = NEXT_INSN (insn))
  18051. +     {
  18052. +       if (GET_CODE (insn) == INSN)
  18053. +     {
  18054. +       unroll_subst_cands (insn, PATTERN (insn), unroll_cands, split_giv_src);
  18055. +     }
  18056. +     }
  18057. + }
  18058. + /* Try to combine split givs from unrolling into one giv to decrease
  18059. +    register pressure and increase scheduling possiblities
  18060. + */
  18061. + static
  18062. + rtx 
  18063. + unroll_subst_cands (insn, pat, unroll_cands, split_giv_src)
  18064. +      rtx insn, pat;
  18065. +      struct unroll_combine_cand **unroll_cands;
  18066. +      rtx *split_giv_src;
  18067. + {
  18068. +   register RTX_CODE code = GET_CODE (pat);
  18069. +   register int i, j;
  18070. +   register char *fmt;
  18071. +   if (GET_CODE (pat) == REG && pat == SET_DEST (PATTERN (insn)))
  18072. +     {
  18073. +       return (pat);
  18074. +     }
  18075. +   switch (code)
  18076. +     {
  18077. +     case HIGH:
  18078. +     case CONST_INT:
  18079. +     case CONST:
  18080. +     case CONST_DOUBLE:
  18081. +     case SYMBOL_REF:
  18082. +     case LABEL_REF:
  18083. +     case PC:
  18084. +     case CC0:
  18085. +       return pat;
  18086. +     case REG:
  18087. +       {
  18088. +     register int regno = REGNO (pat);
  18089. +     if (split_giv_src[regno] && split_giv_src[regno] != (rtx) - 1 
  18090. +         && unroll_cands[REGNO (split_giv_src[regno])])
  18091. +       {
  18092. +         if (loop_dump_stream)
  18093. +           {
  18094. +         fprintf (loop_dump_stream, "   replacing reg%d with reg%d in insn %d\n",
  18095. +               regno, REGNO (split_giv_src[regno]), INSN_UID (insn));
  18096. +           }
  18097. +         return (split_giv_src[regno]);
  18098. +       }
  18099. +       }
  18100. +       return pat;
  18101. +     }
  18102. +   fmt = GET_RTX_FORMAT (code);
  18103. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  18104. +     if (fmt[i] == 'e')
  18105. +       XEXP (pat, i) 
  18106. +     = unroll_subst_cands (insn, XEXP (pat, i), unroll_cands, split_giv_src);
  18107. +     else if (fmt[i] == 'E' || fmt[i] == 'V')
  18108. +       {
  18109. +     for (j = 0; j < XVECLEN (pat, i); j++)
  18110. +       XVECEXP (pat, i, j) 
  18111. +         = unroll_subst_cands (insn, XVECEXP (pat, i, j), unroll_cands,
  18112. +               split_giv_src);
  18113. +       }
  18114. +   return pat;
  18115. + }
  18116. + /* Check that spilt givs remain consistant */
  18117. + static
  18118. + unroll_consistancy_maintained (cur_max_regnum, unroll_cands, reg_inc, insn,
  18119. +                    split_giv_src)
  18120. +      int cur_max_regnum;
  18121. +      struct unroll_combine_cand **unroll_cands;
  18122. +      struct reg_incs *reg_inc;
  18123. +      rtx *split_giv_src;
  18124. +      rtx insn;
  18125. + {
  18126. +   int i;
  18127. +   struct unroll_combine_cand *an_unroll_cand;
  18128. +   for (i = 0; i < cur_max_regnum; i++)
  18129. +     {
  18130. +       if (unroll_cands[i])
  18131. +     {
  18132. +       if (reg_inc[i].invalid)
  18133. +         {
  18134. +           unroll_cands[i] = NULL;
  18135. +         }
  18136. +       else
  18137. +         { /* Check each candidate to see that it was incremented
  18138. +                  by same amount.  */
  18139. +           an_unroll_cand = unroll_cands[i];
  18140. +           while (an_unroll_cand)
  18141. +         {
  18142. +           if (reg_inc[REGNO (an_unroll_cand->reg)].invalid 
  18143. +               || reg_inc[REGNO (an_unroll_cand->reg)].inc_val !=
  18144. +               reg_inc[i].inc_val)
  18145. +             {
  18146. +               split_giv_src[REGNO (an_unroll_cand->reg)] = (rtx) - 1;
  18147. +             }
  18148. +           an_unroll_cand = an_unroll_cand->next;
  18149. +         }
  18150. +         }
  18151. +     }
  18152. +     }
  18153. + }
  18154. + #ifdef STORE_NOT_SET_CC0
  18155. + #ifdef STACK_REGS
  18156. + /* do_spl is called after reload because the reloader decides to spill
  18157. +    fp regs, for no appareant reason, if it is done before.
  18158. + */
  18159. + void
  18160. + do_spl (f)
  18161. +      /* f is the first instruction of a chain of insns for one function */
  18162. +      rtx f;
  18163. + {
  18164. +   register rtx insn;
  18165. +   register int i;
  18166. +   rtx end;
  18167. +   rtx last_insn;
  18168. + #ifndef HAVE_cc0
  18169. +   return;
  18170. + #endif
  18171. +   /* Count the number of loops. */
  18172. +   max_loop_num = 0;
  18173. +   for (insn = f; insn; insn = NEXT_INSN (insn))
  18174. +     {
  18175. +       if (GET_CODE (insn) == NOTE
  18176. +       && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
  18177. +     max_loop_num++;
  18178. +     }
  18179. +   /* Don't waste time if no loops.  */
  18180. +   if (max_loop_num == 0)
  18181. +     return;
  18182. +   doing_spl = 1;
  18183. +   /* Get size to use for tables indexed by uids.
  18184. +      Leave some space for labels allocated by find_and_verify_loops.  */
  18185. +   max_uid_for_loop = get_max_uid () + 1 + max_loop_num * 4;
  18186. +   uid_luid = (int *) alloca (max_uid_for_loop * sizeof (int));
  18187. +   uid_loop_num = (int *) alloca (max_uid_for_loop * sizeof (int));
  18188. +   bzero (uid_luid, max_uid_for_loop * sizeof (int));
  18189. +   bzero (uid_loop_num, max_uid_for_loop * sizeof (int));
  18190. +   /* Allocate tables for recording each loop.  We set each entry, so they need
  18191. +      not be zeroed.  */
  18192. +   loop_number_loop_starts = (rtx *) alloca (max_loop_num * sizeof (rtx));
  18193. +   loop_number_loop_ends = (rtx *) alloca (max_loop_num * sizeof (rtx));
  18194. +   loop_outer_loop = (int *) alloca (max_loop_num * sizeof (int));
  18195. +   loop_invalid = (char *) alloca (max_loop_num * sizeof (char));
  18196. +   loop_number_exit_labels = (rtx *) alloca (max_loop_num * sizeof (rtx));
  18197. +   /* Find and spl each loop.
  18198. +      First, find them, and record them in order of their beginnings.  */
  18199. +   find_and_verify_loops (f);
  18200. +   for (i = max_loop_num - 1; i >= 0; i--)
  18201. +     {
  18202. +       if (loop_number_loop_ends[i])
  18203. +     loop_spl (loop_number_loop_starts[i], loop_number_loop_ends[i], i, 1);
  18204. +     }
  18205. +   doing_spl = 0;
  18206. + }
  18207. + /*
  18208. +    A mini software pipelining - consists of two steps
  18209. +    1) try to get the floating point store to be the last instruction
  18210. +       executed before the jump at the end of loop.
  18211. +    2) try to get the jump to be executed before the floating point
  18212. +       store by retargeting it to the begining of loop and moving
  18213. +       the floating point store to there.  Note that the fall into the
  18214. +       loop will be replaced by a jump around this floating point store
  18215. +    If do_all is 0 then just do step 1
  18216. + */
  18217. + static
  18218. + loop_spl (loop_start, loop_end, loop_num, do_all)
  18219. +      rtx loop_start, loop_end;
  18220. +      int loop_num, do_all;
  18221. + {
  18222. +   rtx insn, jump_insn, mem_addr, base_reg, index_reg, copy_pat, label_insn,
  18223. +     label, p, *index_where, *base_where, pinsn, cc0_insn, where_to_move;
  18224. +   struct reg_incs *reg_inc;
  18225. +   int cur_max_regnum, scale;
  18226. +   char *storage;
  18227. +   if (loop_dump_stream)
  18228. +     {
  18229. +       fprintf (loop_dump_stream, "loop_spl from %d to %d\n",
  18230. +            INSN_UID (loop_start), INSN_UID (loop_end));
  18231. +     }
  18232. +   cur_max_regnum = max_reg_num () + 1;
  18233. +   reg_inc 
  18234. +     = (struct reg_incs *) alloca (cur_max_regnum * (sizeof (struct reg_incs)));
  18235. +   bzero (reg_inc, cur_max_regnum * (sizeof (struct reg_incs)));
  18236. +   insn = PREV_INSN (loop_end);
  18237. +   while (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET 
  18238. +      && rtx_equal_p (SET_DEST (PATTERN (insn)), SET_SRC (PATTERN (insn))))
  18239. +     {
  18240. +       insn = PREV_INSN (insn);
  18241. +     }
  18242. +   if (GET_CODE (insn) != JUMP_INSN)
  18243. +     {
  18244. +       
  18245. +       return;
  18246. +     }
  18247. +   jump_insn = insn;
  18248. +   insn = PREV_INSN (jump_insn);
  18249. +   if (!(GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET 
  18250. +     && SET_DEST (PATTERN (insn)) == cc0_rtx))
  18251. +     {
  18252. +       
  18253. +       return;
  18254. +     }
  18255. +   cc0_insn = insn;
  18256. +   base_reg = NULL;
  18257. +   index_reg = NULL;
  18258. +   scale = 1;
  18259. +   insn = prev_nonnote_insn (insn);
  18260. +   while (1)
  18261. +     {
  18262. +       if (GET_CODE (insn) != INSN)
  18263. +     {
  18264. +       
  18265. +       return;
  18266. +     }
  18267. +       if (GET_CODE (PATTERN (insn)) != SET)
  18268. +     {
  18269. +       
  18270. +       return;
  18271. +     }
  18272. +       if (GET_CODE (SET_DEST (PATTERN (insn))) == REG 
  18273. +       && (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS 
  18274. +        || GET_CODE (SET_SRC (PATTERN (insn))) == MINUS) 
  18275. +       && rtx_equal_p (SET_DEST (PATTERN (insn)),
  18276. +                XEXP (SET_SRC (PATTERN (insn)), 0)) 
  18277. +       && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
  18278. +     {
  18279. +       reg_inc[REGNO (SET_DEST (PATTERN (insn)))].inc_val 
  18280. +         += INTVAL (XEXP (SET_SRC (PATTERN (insn)), 1));
  18281. +       if (GET_CODE (SET_SRC (PATTERN (insn))) == MINUS)
  18282. +         {
  18283. +           reg_inc[REGNO (SET_DEST (PATTERN (insn)))].inc_val *= -1;
  18284. +         }
  18285. +       insn = prev_nonnote_insn (insn);
  18286. +     }
  18287. +       else
  18288. +     {
  18289. +       break;
  18290. +     }
  18291. +     }
  18292. +   if (!(GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET 
  18293. +     && (GET_CODE (SET_SRC (PATTERN (insn))) == REG 
  18294. +     || (GET_CODE (SET_SRC (PATTERN (insn))) == FLOAT_TRUNCATE 
  18295. +     && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG) 
  18296. +     || (GET_CODE (SET_SRC (PATTERN (insn))) == FLOAT_EXTEND 
  18297. +     && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG))
  18298. +     && GET_CODE (SET_DEST (PATTERN (insn))) == MEM 
  18299. +     && (GET_MODE (SET_DEST (PATTERN (insn))) == SFmode 
  18300. +     || GET_MODE (SET_DEST (PATTERN (insn))) == DFmode) 
  18301. +         && GET_MODE (SET_DEST (PATTERN (insn))) == 
  18302. +             GET_MODE (SET_SRC (PATTERN (insn)))
  18303. +       )
  18304. +     )
  18305. +     {
  18306. +       
  18307. +       return;
  18308. +     }
  18309. +   /* if previous fp instruction is fld - no gain */
  18310. +   pinsn = prev_nonnote_insn (insn);
  18311. +   if (INSN_UID (pinsn) < INSN_UID (loop_start))
  18312. +     {
  18313. +       
  18314. +       return;
  18315. +     }
  18316. +   while (pinsn != loop_start)
  18317. +     {
  18318. +       if (GET_CODE (pinsn) == JUMP_INSN || GET_CODE (pinsn) == CODE_LABEL 
  18319. +       || (GET_CODE (pinsn) == INSN && GET_CODE (PATTERN (pinsn)) == SET 
  18320. +        && (GET_MODE (SET_DEST (PATTERN (pinsn))) == SFmode 
  18321. +         || GET_MODE (SET_DEST (PATTERN (pinsn))) == DFmode)
  18322. +       )
  18323. +     )
  18324. +     {
  18325. +       break;
  18326. +     }
  18327. +       pinsn = PREV_INSN (pinsn);
  18328. +     }
  18329. +   if (pinsn == loop_start || GET_CODE (pinsn) == JUMP_INSN 
  18330. +       || GET_CODE (pinsn) == CODE_LABEL)
  18331. +     {
  18332. +       
  18333. +       return;
  18334. +     }
  18335. +   if ((GET_CODE (SET_SRC (PATTERN (pinsn))) == MEM 
  18336. +        || GET_CODE (SET_SRC (PATTERN (pinsn))) == CONST_DOUBLE 
  18337. +        || GET_CODE (SET_SRC (PATTERN (pinsn))) == REG)
  18338. +     )
  18339. +     {
  18340. +       
  18341. +       return;
  18342. +     }
  18343. +   /* We have found the floating point store insn - now try to move it down */
  18344. +   /* Find the registers that are used as bases for the memory access in the
  18345. +      insn */
  18346. +   storage = (char *) oballoc (0);
  18347. +   copy_pat = copy_rtx (PATTERN (insn));
  18348. +   mem_addr = XEXP (SET_DEST (copy_pat), 0);
  18349. +   if (GET_CODE (mem_addr) == PLUS)
  18350. +     {
  18351. +       if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
  18352. +     {
  18353. +       if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == REG 
  18354. +           && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == CONST_INT)
  18355. +         {
  18356. +           index_where = &XEXP (XEXP (mem_addr, 0), 0);
  18357. +           index_reg = XEXP (XEXP (mem_addr, 0), 0);
  18358. +           scale = INTVAL (XEXP (XEXP (mem_addr, 0), 1));
  18359. +         }
  18360. +       else
  18361. +         {
  18362. +           
  18363. +           return;
  18364. +         }
  18365. +       if (GET_CODE (XEXP (mem_addr, 1)) == REG)
  18366. +         {
  18367. +           base_where = &XEXP (mem_addr, 1);
  18368. +           base_reg = XEXP (mem_addr, 1);
  18369. +         }
  18370. +       else if (GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF 
  18371. +            || GET_CODE (XEXP (mem_addr, 1)) == CONST)
  18372. +         {
  18373. +           ;
  18374. +         }
  18375. +       else
  18376. +         {
  18377. +           
  18378. +           return;
  18379. +         }
  18380. +     }
  18381. +       else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
  18382. +     {
  18383. +       /* Take care of non canonicalized expressions */
  18384. +       rtx tmp;
  18385. +       if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == REG 
  18386. +           && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == MULT)
  18387. +         {
  18388. +           tmp = XEXP (XEXP (mem_addr, 0), 0);
  18389. +           XEXP (XEXP (mem_addr, 0), 0) = XEXP (XEXP (mem_addr, 0), 1);
  18390. +           XEXP (XEXP (mem_addr, 0), 1) = tmp;
  18391. +         }
  18392. +       if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) != MULT)
  18393. +         {
  18394. +           
  18395. +           return;
  18396. +         }
  18397. +       if (GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == REG 
  18398. +           && GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1)) == CONST_INT)
  18399. +         {
  18400. +           index_where = &XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
  18401. +           index_reg = XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
  18402. +           scale = INTVAL (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1));
  18403. +         }
  18404. +       else
  18405. +         {
  18406. +           
  18407. +           return;
  18408. +         }
  18409. +       if (GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) != REG)
  18410. +         {
  18411. +           
  18412. +           return;
  18413. +         }
  18414. +       base_where = &XEXP (XEXP (mem_addr, 0), 1);
  18415. +       base_reg = XEXP (XEXP (mem_addr, 0), 1);
  18416. +       if (GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF 
  18417. +           || GET_CODE (XEXP (mem_addr, 1)) == CONST 
  18418. +           || GET_CODE (XEXP (mem_addr, 1)) == CONST_INT)
  18419. +         {
  18420. +           ;
  18421. +         }
  18422. +       else
  18423. +         {
  18424. +           
  18425. +           return;
  18426. +         }
  18427. +     }
  18428. +       else if (GET_CODE (XEXP (mem_addr, 0)) == REG)
  18429. +     {
  18430. +       base_where = &XEXP (mem_addr, 0);
  18431. +       base_reg = XEXP (mem_addr, 0);
  18432. +       if (GET_CODE (XEXP (mem_addr, 1)) == REG)
  18433. +         {
  18434. +           index_where = &XEXP (mem_addr, 1);
  18435. +           index_reg = XEXP (mem_addr, 1);
  18436. +         }
  18437. +     }
  18438. +       else
  18439. +     {
  18440. +       
  18441. +       return;
  18442. +     }
  18443. +     }
  18444. +   else if (GET_CODE (mem_addr) == SYMBOL_REF || GET_CODE (mem_addr) == CONST)
  18445. +     {
  18446. +       ;
  18447. +     }
  18448. +   else if (GET_CODE (mem_addr) == REG)
  18449. +     {
  18450. +       base_reg = mem_addr;
  18451. +       base_where = &XEXP (SET_DEST (copy_pat), 0);
  18452. +     }
  18453. +   else
  18454. +     {
  18455. +       
  18456. +       return;
  18457. +     }
  18458. +   /* Now we know the base index and scale */
  18459. +   if (index_reg && reg_inc[REGNO (index_reg)].inc_val)
  18460. +     {
  18461. +       *index_where = gen_rtx (PLUS, GET_MODE (index_reg), index_reg,
  18462. +        gen_rtx (CONST_INT, 0, reg_inc[REGNO (index_reg)].inc_val * -1));
  18463. +     }
  18464. +   if (base_reg && reg_inc[REGNO (base_reg)].inc_val)
  18465. +     {
  18466. +       *base_where = gen_rtx (PLUS, GET_MODE (base_reg), base_reg,
  18467. +         gen_rtx (CONST_INT, 0, reg_inc[REGNO (base_reg)].inc_val * -1));
  18468. +     }
  18469. + #ifdef REWRITE_ADDRESS
  18470. +   if (recog (copy_pat, insn, 0) < 0)
  18471. +     {
  18472. +       try_to_make_good (SET_DEST (copy_pat));
  18473. +     }
  18474. + #endif
  18475. +   if (recog (copy_pat, insn, 0) < 0)
  18476. +     {
  18477. +       obfree (storage);
  18478. +       
  18479. +       return;
  18480. +     }
  18481. +   if (do_all == 0)
  18482. +     {
  18483. +       where_to_move = cc0_insn;
  18484. +     }
  18485. +   else
  18486. +     {
  18487. +       where_to_move = jump_insn;
  18488. +     }
  18489. +   /* Now move the store with it's new pattern */
  18490. +   PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
  18491. +   NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
  18492. +   NEXT_INSN (insn) = where_to_move;
  18493. +   PREV_INSN (insn) = PREV_INSN (where_to_move);
  18494. +   NEXT_INSN (PREV_INSN (where_to_move)) = insn;
  18495. +   PREV_INSN (where_to_move) = insn;
  18496. +   PATTERN (insn) = copy_pat;
  18497. +   if (loop_dump_stream)
  18498. +     {
  18499. +       fprintf (loop_dump_stream, " moved fp store down\n");
  18500. +     }
  18501. +   if (do_all == 0)
  18502. +     {
  18503. +       
  18504. +       return;
  18505. +     }
  18506. +   /* Now move the store again and add a new jump and label */
  18507. +   if (loop_invalid[loop_num])
  18508. +     {
  18509. +       emit_insn_before (gen_rtx (USE, 0, cc0_rtx), insn);
  18510. +       
  18511. +       return;
  18512. +     }
  18513. +   if (GET_CODE (NEXT_INSN (loop_start)) != CODE_LABEL)
  18514. +     {
  18515. +       emit_insn_before (gen_rtx (USE, 0, cc0_rtx), insn);
  18516. +       
  18517. +       return;
  18518. +     }
  18519. +   label_insn = NEXT_INSN (loop_start);
  18520. +   if (GET_CODE (SET_SRC (PATTERN (jump_insn))) != IF_THEN_ELSE)
  18521. +     {
  18522. +       emit_insn_before (gen_rtx (USE, 0, cc0_rtx), insn);
  18523. +       
  18524. +       return;
  18525. +     }
  18526. + #if 0
  18527. +   if (LABEL_NUSES (label_insn) != 1)
  18528. +     {
  18529. +       emit_insn_before (gen_rtx (USE, 0, cc0_rtx), insn);
  18530. +       
  18531. +       return;
  18532. +     }
  18533. + #endif
  18534. +   /* Make a jump to the old label just before the label*/
  18535. +   p = emit_jump_insn_after (gen_jump (label_insn), 
  18536. +                             PREV_INSN (label_insn));
  18537. +   JUMP_LABEL (p) = label_insn;
  18538. +   emit_barrier_after (p);
  18539. +   /* Add a new label just before the old one */
  18540. +   label = gen_label_rtx ();
  18541. +   label_insn = emit_label_after (label, PREV_INSN (label_insn));
  18542. +   /* Make the jump at the end of the loop jump to the new lable */
  18543. +   if (XEXP (SET_SRC (PATTERN (jump_insn)), 1) == pc_rtx)
  18544. +     {
  18545. +       XEXP (SET_SRC (PATTERN (jump_insn)), 2)
  18546. +         = gen_rtx (LABEL_REF, VOIDmode, label);
  18547. +     }
  18548. +   else
  18549. +     {
  18550. +       XEXP (SET_SRC (PATTERN (jump_insn)), 1)
  18551. +         = gen_rtx (LABEL_REF, VOIDmode, label);
  18552. +     }
  18553. +   ++LABEL_NUSES (label_insn);
  18554. +   JUMP_LABEL (jump_insn) = label_insn;
  18555. +   /* Move the store to just after the new label */
  18556. +   PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
  18557. +   NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
  18558. +   NEXT_INSN (insn) = NEXT_INSN (label_insn);
  18559. +   PREV_INSN (insn) = label_insn;
  18560. +   PREV_INSN (NEXT_INSN (label_insn)) = insn;
  18561. +   NEXT_INSN (label_insn) = insn;
  18562. +   /* Add the store after the jump at the end of the loop */
  18563. +   p = emit_insn_after (PATTERN (insn), jump_insn);
  18564. +   REG_NOTES (p) = REG_NOTES (insn);
  18565. +   if (loop_dump_stream)
  18566. +     {
  18567. +       fprintf (loop_dump_stream, " spl successful\n");
  18568. +     }
  18569. + }
  18570. + #endif
  18571. + #endif
  18572. + /* Element N is first insn in basic block N.
  18573. +    This info lasts until we finish compiling the function.  */
  18574. + extern rtx *basic_block_head;
  18575. + /* Element N is last insn in basic block N.
  18576. +    This info lasts until we finish compiling the function.  */
  18577. + extern rtx *basic_block_end;
  18578. + /* Number of basic blocks in the current function.  */
  18579. + extern int n_basic_blocks;
  18580. + extern regset *basic_block_live_at_start;
  18581. + /*        Move spills out of loops if possible i.e.
  18582. +           if can find a register in the loop that is
  18583. +           alway used to hold a certian spill slot then
  18584. +           1) load the spill slot into that register before the
  18585. +              loop.
  18586. +           2) replace all refernces to the spill slot int the loop with
  18587. +              refernces to that register
  18588. +           3) if the spill slot was updated in the loop and the pseudo
  18589. +              that corresponds to that spill slot is alive at the loop
  18590. +              fallout then write that register back to the spill slot
  18591. +              at the end of the loop.  NOTE that if the pseudo is
  18592. +              alive at any other of the loop exits (if there are any)
  18593. +              and the spill slot is updated in the loop then steps
  18594. +              1) and 2) are NOT done.  
  18595. +           NOTE
  18596. +           a) if the spill slot is only loaded into the register once
  18597. +              throughout the loop and the spill slot is not updated in
  18598. +              the loop then loop_optimize() called from here will
  18599. +              probably handle this.  I say probably because maybe_never
  18600. +              of scan_loop is rather over cautious since it is set
  18601. +              when a jump_insn is encountered but not reset when
  18602. +              the corresponding label is encountered.  
  18603. +           Other optimizations which are done here are trying
  18604. +           to push invariants that were spilled back into the loop
  18605. +           (see push_load_into_loop()).  
  18606. +           Also a straight line pass over the function is made
  18607. +           and whenever a spill slot is loaded into a register
  18608. +           if that spill slot is also valid in some register
  18609. +           then that spill slot is replaced with that register.  
  18610. +           (see peep_spills()).  
  18611. + */
  18612. + void
  18613. + loop_after_global (f, dumpfile)
  18614. +      /* f is the first instruction of a chain of insns for one function */
  18615. +      rtx f;
  18616. +      FILE *dumpfile;
  18617. + {
  18618. +   rtx insn;
  18619. +   int i;
  18620. +   rtx nonlocal_label_list = nonlocal_label_rtx_list ();
  18621. +   register regset tem;
  18622. +   int sav_flag_copy_prop;
  18623. +   int sav_flag_jump_back;
  18624. +   int sav_flag_compare_elim;
  18625. +   int sav_flag_unroll_loops;
  18626. +   int sav_flag_strength_reduce;
  18627. +   sav_flag_copy_prop = flag_copy_prop;
  18628. +   sav_flag_jump_back = flag_jump_back;
  18629. +   sav_flag_compare_elim = flag_compare_elim;
  18630. +   sav_flag_unroll_loops = flag_unroll_loops;
  18631. +   sav_flag_strength_reduce = flag_strength_reduce;
  18632. +   flag_copy_prop = 0;
  18633. +   flag_jump_back = 0;
  18634. +   flag_compare_elim = 0;
  18635. +   flag_unroll_loops = 0;
  18636. +   flag_strength_reduce = 0;
  18637. +   cur_stack_offset = 0;
  18638. +   doing_loop_after_global = 1;
  18639. +   loop_optimize (f, dumpfile);
  18640. +   doing_loop_after_global = 0;
  18641. +   { /* Update basic block start and ends */
  18642. +     register RTX_CODE prev_code = JUMP_INSN;
  18643. +     register RTX_CODE code;
  18644. +     for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
  18645. +       {
  18646. +     code = GET_CODE (insn);
  18647. +     if (code == CODE_LABEL
  18648. +         || (GET_RTX_CLASS (code) == 'i'
  18649. +         && (prev_code == JUMP_INSN
  18650. +             || (prev_code == CALL_INSN
  18651. +             && nonlocal_label_list != 0)
  18652. +             || prev_code == BARRIER)))
  18653. +       i++;
  18654. +     if (code != NOTE)
  18655. +       prev_code = code;
  18656. +       }
  18657. +     if (i > n_basic_blocks)
  18658. +       {
  18659. +         n_basic_blocks = i;
  18660. +         basic_block_head = (rtx *) oballoc (n_basic_blocks * sizeof (rtx));
  18661. +         basic_block_end = (rtx *) oballoc (n_basic_blocks * sizeof (rtx));
  18662. +       }
  18663. +     n_basic_blocks = i;
  18664. +     prev_code = JUMP_INSN;
  18665. +     for (insn = f, i = -1; insn; insn = NEXT_INSN (insn))
  18666. +       {
  18667. +     code = GET_CODE (insn);
  18668. +     /* A basic block starts at label, or after something that can jump.  */
  18669. +     if (code == CODE_LABEL
  18670. +         || (GET_RTX_CLASS (code) == 'i'
  18671. +         && (prev_code == JUMP_INSN
  18672. +             || (prev_code == CALL_INSN
  18673. +             && nonlocal_label_list != 0)
  18674. +             || prev_code == BARRIER)))
  18675. +       {
  18676. +         basic_block_head[++i] = insn;
  18677. +         if (i >= n_basic_blocks)
  18678. +           {
  18679. +         abort ();
  18680. +           }
  18681. +         basic_block_end[i] = insn;
  18682. +       }
  18683. +     else if (GET_RTX_CLASS (code) == 'i')
  18684. +       {
  18685. +         basic_block_end[i] = insn;
  18686. +       }
  18687. +     if (code != NOTE
  18688. +         && !(prev_code == CALL_INSN && code == INSN
  18689. +          && GET_CODE (PATTERN (insn)) == CLOBBER))
  18690. +       prev_code = code;
  18691. +       }
  18692. +   }
  18693. +   flag_copy_prop = sav_flag_copy_prop;
  18694. +   flag_jump_back = sav_flag_jump_back;
  18695. +   flag_compare_elim = sav_flag_compare_elim;
  18696. +   flag_unroll_loops = sav_flag_unroll_loops;
  18697. +   flag_strength_reduce = sav_flag_strength_reduce;
  18698. + }
  18699. + /* x is a spill slot and hence is unaliased
  18700. + */
  18701. + static int
  18702. + spill_invariant_p (x)
  18703. +      register rtx x;
  18704. + {
  18705. +   register int i;
  18706. +   register enum rtx_code code;
  18707. +   register char *fmt;
  18708. +   int conditional = 0;
  18709. +   if (x == 0)
  18710. +     return 1;
  18711. +   code = GET_CODE (x);
  18712. +   switch (code)
  18713. +     {
  18714. +     case CONST_INT:
  18715. +     case CONST_DOUBLE:
  18716. +     case SYMBOL_REF:
  18717. +     case CONST:
  18718. +       return 1;
  18719. +     case LABEL_REF:
  18720. +       /* A LABEL_REF is normally invariant, however, if we are unrolling
  18721. +      loops, and this label is inside the loop, then it isn't invariant.
  18722. +      This is because each unrolled copy of the loop body will have
  18723. +      a copy of this label.  If this was invariant, then an insn loading
  18724. +      the address of this label into a register might get moved outside
  18725. +      the loop, and then each loop body would end up using the same label.
  18726. +      We don't know the loop bounds here though, so just fail for all
  18727. +      labels.  */
  18728. +       if (flag_unroll_loops)
  18729. +     return 0;
  18730. +       else
  18731. +     return 1;
  18732. +     case PC:
  18733. +     case CC0:
  18734. +     case UNSPEC_VOLATILE:
  18735. +       return 0;
  18736. +     case REG:
  18737. +       /* We used to check RTX_UNCHANGING_P (x) here, but that is invalid
  18738. +      since the reg might be set by initialization within the loop.  */
  18739. +       if (x == frame_pointer_rtx || x == arg_pointer_rtx)
  18740. +     return 1;
  18741. +       if (loop_has_call
  18742. +       && REGNO (x) < FIRST_PSEUDO_REGISTER && call_used_regs[REGNO (x)])
  18743. +     return 0;
  18744. +       if (n_times_set[REGNO (x)] < 0)
  18745. +     return 2;
  18746. +       return n_times_set[REGNO (x)] == 0;
  18747. +     case MEM:
  18748. +       /* Read-only items (such as constants in a constant pool) are
  18749. +      invariant if their address is.  */
  18750. +       if (RTX_UNCHANGING_P (x))
  18751. +     break;
  18752. +       /* If we filled the table (or had a subroutine call), any location
  18753. +      in memory could have been clobbered.  */
  18754. +       if (unknown_address_altered
  18755. +       /* Don't mess with volatile memory references.  */
  18756. +       || MEM_VOLATILE_P (x))
  18757. +     return 0;
  18758. +       /* See if there is any dependence between a store and this load.  */
  18759. +       for (i = loop_store_mems_idx - 1; i >= 0; i--)
  18760. +     if (rtx_equal_p (XEXP (loop_store_mems[i], 0), XEXP (x, 0)))
  18761. +       {
  18762. +         return 0;
  18763. +       }
  18764. +       /* It's not invalidated by a store in memory
  18765. +      but we must still verify the address is invariant.  */
  18766. +       break;
  18767. +     case ASM_OPERANDS:
  18768. +       /* Don't mess with insns declared volatile.  */
  18769. +       if (MEM_VOLATILE_P (x))
  18770. +     return 0;
  18771. +     }
  18772. +   fmt = GET_RTX_FORMAT (code);
  18773. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  18774. +     {
  18775. +       if (fmt[i] == 'e')
  18776. +     {
  18777. +       int tem = invariant_p (XEXP (x, i));
  18778. +       if (tem == 0)
  18779. +         return 0;
  18780. +       if (tem == 2)
  18781. +         conditional = 1;
  18782. +     }
  18783. +       else if (fmt[i] == 'E')
  18784. +     {
  18785. +       register int j;
  18786. +       for (j = 0; j < XVECLEN (x, i); j++)
  18787. +         {
  18788. +           int tem = invariant_p (XVECEXP (x, i, j));
  18789. +           if (tem == 0)
  18790. +         return 0;
  18791. +           if (tem == 2)
  18792. +         conditional = 1;
  18793. +         }
  18794. +     }
  18795. +     }
  18796. +   return 1 + conditional;
  18797. + }
  18798. + extern struct reload_slot_info reload_slots[];
  18799. + extern num_reload_stack_slots;
  18800. + extern char call_used_regs[];
  18801. + extern char **insn_name_ptr;
  18802. + static struct spill_candidates
  18803. +   {
  18804. +     /* The stack slot reloaded into this candidate */
  18805. +     rtx reload_slot;
  18806. +     /* The insn that does the reloading */
  18807. +     rtx reload_insn;
  18808. +     /* The rtx of the hard register that is reloaded into */
  18809. +     rtx hard_reg;
  18810. +     /* The mode of the reload slot */
  18811. +     enum machine_mode mode;
  18812. +     /* Number of times this candidate is set */
  18813. +     int num_times_set;
  18814. +     /* The pseduo register corresponding to the stack slot */
  18815. +     int pseudo_reg;
  18816. +     int cur_stack_offset;
  18817. +     int reload_indx;
  18818. +     /* A linked list of candidates on the same reload stack slot */
  18819. +     struct spill_candidates *link_cand;
  18820. +     struct spill_candidates *head_cand;
  18821. +     unsigned is_head:1;
  18822. +     unsigned has_link:1;
  18823. +     /* if 1 this candidate is invalid */
  18824. +     unsigned disregard:1;
  18825. +     /* if 1 the reload stack slot is stored into */
  18826. +     unsigned slot_updated_in_loop:1;
  18827. +     /* if 1 the pseduo register is live at the loop fall out */
  18828. +     unsigned live_at_fall_out:1;
  18829. +     /* if 1 the pseduo register is live at a loop jump out */
  18830. +     unsigned live_at_jump_out:1;
  18831. +     /* if 1 the value in the candidate hard register must be
  18832. +        updated into the reload stack slot */
  18833. +     unsigned must_update_reload:1;
  18834. +     /* if 1 then the candidate hard register was loaded with the
  18835. +        reload stack slot before it was used */
  18836. +     unsigned first_set_to_reload:1;
  18837. +     /* if 1 then the candidate's spill slot has been updated and
  18838. +        the candidate is out of synch with it's spill slot intel1a */
  18839. +     unsigned slot_updated:1;
  18840. +   }
  18841. + spill_candidate[FIRST_PSEUDO_REGISTER];
  18842. + static int all_candidates_invalid = 0;
  18843. + static int num_spill_candidates_found = 0;
  18844. + static int *insns_moved_out;
  18845. + static int have_flow_analysis = 0;
  18846. + /* Find all candidates for spill slot optimization over the loop and
  18847. +    move them out. Also try to push spilled invariants back into the
  18848. +    loop
  18849. + */
  18850. + static
  18851. + void 
  18852. + move_spills_out (loop_start, loop_end)
  18853. +      rtx loop_start;
  18854. +      rtx loop_end;
  18855. + {
  18856. +   rtx insn;
  18857. +   int i, is_loop_exit, regno, indx;
  18858. +   insns_moved_out = (int *) alloca ((max_uid_for_loop + 1) * sizeof (int));
  18859. +   bzero (insns_moved_out, (max_uid_for_loop + 1) * sizeof (int));
  18860. +   num_reload_stack_slots = 0;
  18861. +   num_spill_candidates_found = 0;
  18862. +   bzero (spill_candidate, FIRST_PSEUDO_REGISTER * sizeof (spill_candidate[0]));
  18863. +   for (i=0; i<FIRST_PSEUDO_REGISTER; i++)
  18864. +     {
  18865. +       spill_candidate[i].reload_indx = -1;
  18866. +     }
  18867. +   insn = loop_start;
  18868. +   while (insn != PREV_INSN (loop_end))
  18869. +     {
  18870. +       if (GET_CODE (insn) == INSN && RTX_IS_SPILL_P (insn) 
  18871. +       && GET_CODE (PATTERN (insn)) == SET 
  18872. +       && GET_CODE (SET_DEST (PATTERN (insn))) == REG 
  18873. +       && GET_CODE (SET_SRC (PATTERN (insn))) == MEM 
  18874. +       && is_a_stack_slot (SET_SRC (PATTERN (insn)))
  18875. +       && (regno = REGNO (SET_DEST (PATTERN (insn)))) < FIRST_PSEUDO_REGISTER
  18876. +     )
  18877. +     {
  18878. +       indx = -1;
  18879. +       if (!is_a_reload_stack_slot (SET_SRC (PATTERN (insn)), &indx, 0, 0))
  18880. +         {
  18881. +           if (num_reload_stack_slots >= MAX_RELOAD_STACK_SLOTS)
  18882. +             {
  18883. +               return;
  18884. +             }
  18885. +           reload_slots[num_reload_stack_slots].cur_stack_offset = 0;
  18886. +           reload_slots[num_reload_stack_slots].reload_stack_mode = -1;
  18887. +           reload_slots[num_reload_stack_slots].is_loaded_to_reg = -1;
  18888. +           reload_slots[num_reload_stack_slots].reload_slot_updated = 0;
  18889. +           reload_slots[num_reload_stack_slots].stack_slot_pseudo_reg 
  18890. +         = SPILL_PSEUDO (insn);
  18891. +           reload_slots[num_reload_stack_slots].reload_insn = insn; 
  18892. +           reload_slots[num_reload_stack_slots++].reload_stack_slot 
  18893. +         = SET_SRC (PATTERN (insn));
  18894. +         }
  18895. +       else
  18896. +         { /* We have already encountered this reload slot - it
  18897. +                  must always be a reload slot of the same pseudo */
  18898. +           if (reload_slots[indx].stack_slot_pseudo_reg !=
  18899. +           SPILL_PSEUDO (insn))
  18900. +         {
  18901. +           reload_slots[indx].reload_stack_mode == -2;
  18902. +         }
  18903. +         }
  18904. +       if (indx == -1) 
  18905. +         {
  18906. +           indx = num_reload_stack_slots - 1;
  18907. +         }
  18908. +       if (!(spill_candidate[regno].pseudo_reg == 0 
  18909. +         || spill_candidate[regno].pseudo_reg == SPILL_PSEUDO (insn)))
  18910. +         { /* Candidate can be for only one spilled pseudo reg */
  18911. +               reload_slots[indx].reload_stack_mode = -2;
  18912. +               if (spill_candidate[regno].reload_indx != -1)
  18913. +                 {
  18914. +                   reload_slots[spill_candidate[regno].reload_indx].reload_stack_mode = -2;
  18915. +                 }
  18916. +         }
  18917. +           else if (spill_candidate[regno].reload_indx != -1
  18918. +                    && spill_candidate[regno].reload_indx != indx)
  18919. +             { /* Candidates can only be for one reload slot */
  18920. +               reload_slots[indx].reload_stack_mode = -2;
  18921. +               reload_slots[spill_candidate[regno].reload_indx].reload_stack_mode = -2;
  18922. +             }
  18923. +           else 
  18924. +         {
  18925. +               spill_candidate[regno].pseudo_reg = SPILL_PSEUDO (insn);
  18926. +               spill_candidate[regno].reload_indx = indx;
  18927. +         }
  18928. +     }
  18929. +       insn = NEXT_INSN (insn);
  18930. +     }
  18931. +   all_candidates_invalid = 0;
  18932. +   insn = loop_start;
  18933. +   while (insn != (loop_end))
  18934. +     {
  18935. +       if (GET_CODE (insn) == INSN)
  18936. +     {
  18937. +       mark_spill_candidates (insn, PATTERN (insn));
  18938. +       if (all_candidates_invalid)
  18939. +         {
  18940. +           return;
  18941. +         }
  18942. +     }
  18943. +       else if (GET_CODE (insn) == JUMP_INSN)
  18944. +     { /* Check if this is a loop exit */
  18945. +       is_loop_exit = check_if_jumps_out_of_loop (PATTERN (insn), 1);
  18946. +       /* Verify which spill candidates remian valid */
  18947. +       if (num_spill_candidates_found)
  18948. +         verify_spill_candidates (insn, is_loop_exit);
  18949. +       if (all_candidates_invalid)
  18950. +         {
  18951. +           return;
  18952. +         }
  18953. +     }
  18954. +       else if (GET_CODE (insn) == CODE_LABEL && num_spill_candidates_found)
  18955. +     {
  18956. +       /* Verify which spill candidates remian valid */
  18957. +       verify_spill_candidates (insn, 0);
  18958. +     }
  18959. +       insn = NEXT_INSN (insn);
  18960. +     }
  18961. +   if (num_spill_candidates_found && !all_candidates_invalid)
  18962. +     {
  18963. +       int i;
  18964. +       rtx rn, prev, link;
  18965. +       if (!simplejump_p (PREV_INSN (loop_end)))
  18966. +     mark_regs_alive_at_exit (NEXT_INSN (loop_end), 1);
  18967. +       if (!all_candidates_invalid)
  18968. +     {
  18969. +       move_spill_movables (loop_start, loop_end);
  18970. +       for (rn = loop_start; rn != loop_end; rn = NEXT_INSN (rn))
  18971. +         {
  18972. +           if ((GET_CODE (rn) == INSN || GET_CODE (rn) == JUMP_INSN
  18973. +            || GET_CODE (rn) == CALL_INSN) && LOG_LINKS (rn))
  18974. +         {
  18975. +           for (prev = 0, link = LOG_LINKS (rn); link;
  18976. +                prev = link, link = XEXP (link, 1))
  18977. +             {
  18978. +               if (insns_moved_out[INSN_UID (XEXP (link, 0))])
  18979. +             {
  18980. +               if (prev)
  18981. +                 XEXP (prev, 1) = XEXP (link, 1);
  18982. +               else
  18983. +                 LOG_LINKS (rn) = XEXP (link, 1);
  18984. +             }
  18985. +             }
  18986. +         }
  18987. +         }
  18988. +     }
  18989. +     }
  18990. +   if (unknown_address_altered)
  18991. +     {
  18992. +       return;
  18993. +     }
  18994. +   for (i = 0; i < num_reload_stack_slots; i++)
  18995. +     {
  18996. +       if (flag_push_load_into_loop
  18997. +       && reload_slots[i].reload_slot_updated == 0 
  18998. +       /*&& reload_slots[i].reload_stack_mode != -2 
  18999. +       && reload_slots[i].is_loaded_to_reg != -1 
  19000. +       && !spill_candidate[reload_slots[i].is_loaded_to_reg].has_link 
  19001. +       && spill_candidate[reload_slots[i].is_loaded_to_reg].disregard 
  19002. +       && spill_candidate[reload_slots[i].is_loaded_to_reg].live_at_jump_out == 0 
  19003. +           && spill_candidate[reload_slots[i].is_loaded_to_reg].live_at_fall_out == 0
  19004. +           */
  19005. +     )
  19006. +     {
  19007. +       /* This is a reload slot that was never updated in loop
  19008. +              but could not be lifted only because the register it is
  19009. +              loaded into was also set to something else in loop.
  19010. +              Lets see if the reload slot was set in the basic block
  19011. +              just prior to the loop by some inexpensive operation.
  19012. +              (particularly a move from memory into a register and
  19013. +              a move of that register onto stack). If so lets
  19014. +              replace each load of the reload slot in the loop with
  19015. +              a load of the memory and delete the code that loaded
  19016. +              and spilled it outside the loop.
  19017. +              This corrects the preloading of loop invariants that
  19018. +              could not be held in registers over the loop
  19019. +            */
  19020. +       push_load_into_loop (loop_start, loop_end, i);
  19021. +     }
  19022. +     }
  19023. + }
  19024. + /* Move the valid spill slot candidates out of the loop and
  19025. +    replace the spill slot with the register throughout the loop.
  19026. +    Also update the spill slot after the loop if this is necessary */
  19027. + static
  19028. + void 
  19029. + move_spill_movables (loop_start, loop_end)
  19030. +      rtx loop_start, loop_end;
  19031. + {
  19032. +   rtx insn;
  19033. +   int i, indx, all_are_ok;
  19034. +   struct spill_candidates *link_cand;
  19035. +   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  19036. +     {
  19037. +       if (spill_candidate[i].disregard == 0 && spill_candidate[i].reload_insn 
  19038. +       && spill_candidate[i].num_times_set == n_times_set[i])
  19039. +     {
  19040. +       is_a_reload_stack_slot (spill_candidate[i].reload_slot, &indx, 0, 0);
  19041. +           /* Sanity check */
  19042. +           if (spill_candidate[i].reload_indx != indx)
  19043. +             {
  19044. +               abort ();
  19045. +             }
  19046. +       if (reload_slots[indx].reload_stack_mode == -2)
  19047. +         {/* The stack slot was used in some other mode than the
  19048. +                  load to the hard reg */
  19049. +               spill_candidate[i].disregard = 1;
  19050. +           continue;
  19051. +         }
  19052. +       if (!spill_candidate[i].has_link)
  19053. +         {
  19054. +           all_are_ok = 1;
  19055. +         }
  19056. +       else if (spill_candidate[i].is_head)
  19057. +         {
  19058. +           /* This is a candidate that is the head of a chain of
  19059. +                  candidates that all contain the same reload slot.
  19060. +                  Go over the linked list to see if all are ok;
  19061. +               */
  19062. +           all_are_ok = 1;
  19063. +           link_cand = spill_candidate[i].link_cand;
  19064. +           while (link_cand)
  19065. +         {
  19066. +           all_are_ok = all_are_ok 
  19067. +             && link_cand->disregard == 0 
  19068. +             && link_cand->num_times_set == 1 
  19069. +             && n_times_set[REGNO (link_cand->hard_reg)] == 1 
  19070. +             && link_cand->reload_insn;
  19071. +           /* So it won't be processed again */
  19072. +           link_cand->disregard = 1;
  19073. +           link_cand = link_cand->link_cand;
  19074. +         }
  19075. +           if (spill_candidate[i].num_times_set != 1)
  19076. +         {
  19077. +           all_are_ok = 0;
  19078. +         }
  19079. +           if (all_are_ok == 0)
  19080. +             {
  19081. +           spill_candidate[i].disregard = 1;
  19082. +         }
  19083. +         }
  19084. +       else
  19085. +         {
  19086. +           all_are_ok = 0;
  19087. +         }
  19088. +       if (all_are_ok)
  19089. +         {
  19090. +           /* Move the reload insn to just before loop_start */
  19091. +           if (loop_dump_stream)
  19092. +             {
  19093. +               fprintf (loop_dump_stream,
  19094. +               "insn %d moved out of loop, stack slot held in reg %d over loop\n",
  19095. +               INSN_UID (spill_candidate[i].reload_insn), i);
  19096. +               if (spill_candidate[i].is_head)
  19097. +                 {
  19098. +               fprintf (loop_dump_stream, " these regs also shadow the stack slot:");
  19099. +                   link_cand = spill_candidate[i].link_cand;
  19100. +                   while (link_cand)
  19101. +                 {
  19102. +                   fprintf (loop_dump_stream, " %d", REGNO (link_cand->hard_reg));
  19103. +                   link_cand = link_cand->link_cand;
  19104. +                 }
  19105. +               fprintf (loop_dump_stream, "\n");
  19106. +                 }
  19107. +             }
  19108. +           insn = spill_candidate[i].reload_insn;
  19109. +           NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
  19110. +           PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
  19111. +           NEXT_INSN (insn) = loop_start;
  19112. +           PREV_INSN (insn) = PREV_INSN (loop_start);
  19113. +           NEXT_INSN (PREV_INSN (loop_start)) = insn;
  19114. +           PREV_INSN (loop_start) = insn;
  19115. +           if (INSN_UID (insn) <= max_uid_for_loop)
  19116. +         {
  19117. +           insns_moved_out[INSN_UID (insn)] = 1;
  19118. +         }
  19119. +           if (spill_candidate[i].live_at_fall_out 
  19120. +           && spill_candidate[i].slot_updated_in_loop)
  19121. +         {
  19122. +           emit_insn_after (gen_rtx (SET, 0, spill_candidate[i].reload_slot,
  19123. +                         spill_candidate[i].hard_reg),
  19124. +                    loop_end);
  19125. +         }
  19126. +         }
  19127. +     }
  19128. +       else
  19129. +     {
  19130. +       spill_candidate[i].disregard = 1;
  19131. +       if (spill_candidate[i].has_link && spill_candidate[i].is_head)
  19132. +         {  /* invalidate the whole chain */
  19133. +           link_cand = spill_candidate[i].link_cand;
  19134. +           while (link_cand)
  19135. +         {
  19136. +           link_cand->disregard = 1;
  19137. +           link_cand = link_cand->link_cand;
  19138. +         }
  19139. +         }
  19140. +     }
  19141. +     }
  19142. +   /* Where ever a reload_slot that is contained is a valid candidate
  19143. +      appears in the loop - replace it with that hard_reg */
  19144. +   insn = loop_start;
  19145. +   while (insn != loop_end)
  19146. +     {
  19147. +       if (GET_CODE (insn) == INSN)
  19148. +     {
  19149. +           undobuf.num_undo = 0;
  19150. +           undobuf.storage = (char *) oballoc (0);
  19151. +       replace_spill_slots (insn, PATTERN (insn), &PATTERN (insn));
  19152. +       replace_linked_regs (insn, PATTERN (insn));
  19153. +     }
  19154. +       insn = NEXT_INSN (insn);
  19155. +     }
  19156. + }
  19157. + /* If pat jumps out of the loop then mark all candidates that
  19158. +    correspond to pseudos that are alive at the target of the jump,
  19159. +    and return 1
  19160. + */
  19161. + static
  19162. + int 
  19163. + check_if_jumps_out_of_loop (pat, do_mark)
  19164. +      rtx pat;
  19165. +      int do_mark;
  19166. + {
  19167. +   rtx target;
  19168. +   int ret_val = 0;
  19169. +   int i;
  19170. +   switch (GET_CODE (pat))
  19171. +     {
  19172. +     case PC:
  19173. +     case USE:
  19174. +     case CLOBBER:
  19175. +     case REG:
  19176. +     case MEM:
  19177. +     case CONST_INT:
  19178. +     case CONST_DOUBLE:
  19179. +     case RETURN:
  19180. +       return (ret_val);
  19181. +     case CONST:
  19182. +       /* There could be a label reference in here.  */
  19183. +       return (check_if_jumps_out_of_loop (XEXP (pat, 0), do_mark));
  19184. +     case PLUS:
  19185. +     case MINUS:
  19186. +     case MULT:
  19187. +     case LSHIFT:
  19188. +       ret_val = check_if_jumps_out_of_loop (XEXP (pat, 0), do_mark);
  19189. +       ret_val = ret_val | check_if_jumps_out_of_loop (XEXP (pat, 1), do_mark);
  19190. +       return (ret_val);
  19191. +     case SIGN_EXTEND:
  19192. +     case ZERO_EXTEND:
  19193. +       return (check_if_jumps_out_of_loop (XEXP (pat, 0), do_mark));
  19194. +     case LABEL_REF:
  19195. +       if (LABEL_OUTSIDE_LOOP_P (pat))
  19196. +     { /* This is a jump to outside of loop */
  19197. +       if (do_mark)
  19198. +         {
  19199. +           target = XEXP (pat, 0);
  19200. +           /* Now mark all those pseudo regs not dead at entry
  19201. +              to the target block */
  19202. +           mark_regs_alive_at_exit (target, 0);
  19203. +         }
  19204. +       ret_val = 1;
  19205. +     }
  19206. +       return (ret_val);;
  19207. +     case SET:
  19208. +       /* If this is not setting pc, ignore.  */
  19209. +       if (SET_DEST (pat) == pc_rtx)
  19210. +     ret_val = check_if_jumps_out_of_loop (SET_SRC (pat), do_mark);
  19211. +       return (ret_val);
  19212. +     case IF_THEN_ELSE:
  19213. +       ret_val = check_if_jumps_out_of_loop (XEXP (pat, 1), do_mark);
  19214. +       ret_val = ret_val | check_if_jumps_out_of_loop (XEXP (pat, 2), do_mark);
  19215. +       return (ret_val);
  19216. +     case PARALLEL:
  19217. +     case ADDR_VEC:
  19218. +     case ADDR_DIFF_VEC:
  19219. +       all_candidates_invalid = 1;
  19220. +       return(1);
  19221. +     default:
  19222. +       /* Nothing else should occur in a JUMP_INSN.  */
  19223. +       abort ();
  19224. +     }
  19225. + }
  19226. + /*
  19227. +   block_head, or the first nonnote insn after block_head (if block_head
  19228. +   is a note insn), is the head of a block that is the target of a loop
  19229. +   exit. if is_loop_fallout is 1 then the loop exit is the normal end of
  19230. +   the loop where the loop falls out, otherwise the loop exit was a jump
  19231. +   out of the loop. Any candidates whose pseudos are alive at the
  19232. +   start of the block are marked (i.e. the stack slot which
  19233. +   corresponds to the pseudo must be updated at this loop exit)
  19234. +   if the loop exit is NOT the loop fallout then we mark this
  19235. +   candidate as not valid
  19236. + */
  19237. + static
  19238. + void 
  19239. + mark_regs_alive_at_exit (block_head, is_loop_fallout)
  19240. +      rtx block_head;
  19241. +      int is_loop_fallout;
  19242. + {
  19243. +   int i, found, pseudo_regno, block_num, offset, bit;
  19244. +   rtx org_block_head = block_head;
  19245. +   i = 0;
  19246. +   found = 0;
  19247. +   /* Find which block block_head is the head of */
  19248. +   if (is_loop_fallout)
  19249. +     {
  19250. +       while (i < n_basic_blocks && !found)
  19251. +         {
  19252. +           if (basic_block_head[i] == block_head)
  19253. +         {
  19254. +           found = 1;
  19255. +         }
  19256. +           else
  19257. +         {
  19258. +           i++;
  19259. +         }
  19260. +         }
  19261. +     }
  19262. +   if (!found)
  19263. +     {
  19264. +       while (block_head && GET_CODE (block_head) != CODE_LABEL 
  19265. +          && GET_RTX_CLASS (GET_CODE (block_head)) != 'i')
  19266. +         {
  19267. +           block_head = NEXT_INSN (block_head);
  19268. +         }
  19269. +       if (block_head == NULL)
  19270. +         {
  19271. +           if (!is_loop_fallout)
  19272. +         { /* block_head must have been a label upon entry and hence
  19273. +                  should not be null now */
  19274. +           abort ();
  19275. +         }
  19276. +           return;
  19277. +         }
  19278. +       i = 0;
  19279. +       while (i < n_basic_blocks && !found)
  19280. +         {
  19281. +           if (basic_block_head[i] == block_head)
  19282. +         {
  19283. +           found = 1;
  19284. +         }
  19285. +           else
  19286. +         {
  19287. +           i++;
  19288. +         }
  19289. +         }
  19290. +     }
  19291. +   if (!found)
  19292. +     {
  19293. +       all_candidates_invalid = 1;
  19294. +       return;
  19295. +     }
  19296. +   block_num = i;
  19297. +   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  19298. +     {
  19299. +       if (spill_candidate[i].reload_slot == NULL)
  19300. +         { /* A jump out of the loop before it is known
  19301. +              if this slot will become a candidate - so
  19302. +              just mark it to never become a candidate.
  19303. +              Actually we could remember this jump and
  19304. +              mark the candidate accordingly in the future
  19305. +              but this seems like too much work */
  19306. +           spill_candidate[i].disregard = 1;
  19307. +         }
  19308. +       else
  19309. +       if (spill_candidate[i].disregard == 0 
  19310. +       && spill_candidate[i].reload_slot)
  19311. +     { /* This candidate is still valid */
  19312. +       /* Find the pseudo reg that corresponds to this spill slot */
  19313. +       pseudo_regno = spill_candidate[i].pseudo_reg;
  19314. +       if (pseudo_regno < FIRST_PSEUDO_REGISTER)
  19315. +         {
  19316. +           abort ();
  19317. +         }
  19318. +       /* See if this pseudo reg is alive at the beginning of
  19319. +              the block that begins at block_head*/
  19320. +       offset = pseudo_regno / REGSET_ELT_BITS;
  19321. +       bit = 1 << (pseudo_regno % REGSET_ELT_BITS);
  19322. +       if (basic_block_live_at_start[block_num][offset] & bit)
  19323. +         {
  19324. +           if (!is_loop_fallout)
  19325. +         { /* Don't want to handle pseudo's that are alive
  19326. +                      at targets of jumps out of the loop */
  19327. +           spill_candidate[i].disregard = 1;
  19328. +           spill_candidate[i].live_at_jump_out = 1;
  19329. +         }
  19330. +           else
  19331. +         {
  19332. +           spill_candidate[i].live_at_fall_out = 1;
  19333. +         }
  19334. +         }
  19335. +     }
  19336. +     }
  19337. + }
  19338. + /* 
  19339. +   Verfiy that all spill candidates are still valid
  19340. + */
  19341. + static
  19342. + void 
  19343. + verify_spill_candidates (insn, is_loop_exit)
  19344. +      rtx insn;
  19345. +      int is_loop_exit;
  19346. + {
  19347. +   int i;
  19348. +   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  19349. +     {
  19350. +       /* intel1a */
  19351. +       spill_candidate[i].slot_updated = 0;
  19352. +       if (spill_candidate[i].must_update_reload)
  19353. +     {
  19354. +       spill_candidate[i].disregard = 1;
  19355. +     }
  19356. +       if (GET_CODE (insn) == CODE_LABEL)
  19357. +     {
  19358. +       spill_candidate[i].first_set_to_reload = 0;
  19359. +     }
  19360. +     }
  19361. + }
  19362. + #ifndef max
  19363. + #define max(a,b) ((a) < (b) ? (b) : (a))
  19364. + #endif
  19365. + /* Update the spill slot candidate info according to what body does */
  19366. + static
  19367. + void 
  19368. + mark_spill_candidates (insn, body)
  19369. +      rtx insn;
  19370. +      rtx body;
  19371. + {
  19372. +   int regno, i, dummy, indx, cand_num, j, n_regs;
  19373. +   if (GET_CODE (body) == SET)
  19374. +     {
  19375. +       if (GET_CODE (SET_DEST (body)) != REG
  19376. +           && GET_CODE (SET_DEST (body)) != SUBREG)
  19377. +     {
  19378. +       spill_handle_regs_mentioned (SET_DEST (body));
  19379. +     }
  19380. +       spill_handle_regs_mentioned (SET_SRC (body));
  19381. +       if (GET_CODE (SET_DEST (body)) == SUBREG
  19382. +            && GET_CODE (SUBREG_REG (SET_DEST (body))) == REG 
  19383. +        && REGNO (SUBREG_REG (SET_DEST (body))) < FIRST_PSEUDO_REGISTER)
  19384. +     {
  19385. +       regno = REGNO (SUBREG_REG (SET_DEST (body)));
  19386. +       n_regs 
  19387. +         = max (HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body))),
  19388. +                HARD_REGNO_NREGS (regno, 
  19389. +                                  GET_MODE (SUBREG_REG (SET_DEST (body)))));
  19390. +       for (j = 0; j < n_regs; j++)
  19391. +         {
  19392. +           spill_candidate[regno + j].disregard = 1;
  19393. +           if (spill_candidate[regno + j].reload_indx != -1)
  19394. +             {
  19395. +               reload_slots[spill_candidate[regno + j].
  19396. +                   reload_indx].reload_stack_mode = -2;
  19397. +             }
  19398. +         }
  19399. +     }
  19400. +       else if (GET_CODE (SET_DEST (body)) == REG 
  19401. +            && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER)
  19402. +     {
  19403. +       /* if body sets a hard register it is of interest */
  19404. +       regno = REGNO (SET_DEST (body));
  19405. +           n_regs = HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body)));
  19406. +           if (n_regs > 1)
  19407. +             {
  19408. +               for (j = 0; j < n_regs; j++)
  19409. +                 {
  19410. +               spill_candidate[regno + j].disregard = 1;
  19411. +                 }
  19412. +             }
  19413. +       spill_candidate[regno].num_times_set++;
  19414. +       if (GET_CODE (SET_SRC (body)) == MEM 
  19415. +           && is_a_reload_stack_slot (SET_SRC (body), &indx, 0, 0))
  19416. +         { /* It sets it to the value in a reload stack slot 
  19417. +              The stack slot must always be used in the same mode
  19418. +                  as it is used to reload the hard register
  19419. +               */
  19420. +               /* intel1a */
  19421. +           spill_candidate[regno].slot_updated = 0;
  19422. +           if (reload_slots[indx].reload_stack_mode == -1)
  19423. +         {
  19424. +           reload_slots[indx].reload_stack_mode 
  19425. +              = GET_MODE (SET_SRC (body));
  19426. +         }
  19427. +           else if (reload_slots[indx].reload_stack_mode == -2 
  19428. +                || reload_slots[indx].reload_stack_mode 
  19429. +                      != GET_MODE (SET_SRC (body)))
  19430. +         {
  19431. +           /* reload slot not always used in same mode */
  19432. +           reload_slots[indx].reload_stack_mode = -2;
  19433. +           spill_candidate[regno].disregard = 1;
  19434. +         }
  19435. +           if (!spill_candidate[regno].disregard)
  19436. +         {
  19437. +           if (spill_candidate[regno].reload_indx != -1
  19438. +               && spill_candidate[regno].reload_indx != indx)
  19439. +             { /* Same reg loads more than one reload slot -
  19440. +                          disregard it */
  19441. +               reload_slots[indx].reload_stack_mode = -2;
  19442. +               reload_slots[spill_candidate[regno].reload_indx].reload_stack_mode = -2;
  19443. +               spill_candidate[regno].disregard = 1;
  19444. +             }
  19445. +           else
  19446. +             {
  19447. +               num_spill_candidates_found++;
  19448. +               spill_candidate[regno].first_set_to_reload = 1;
  19449. +               spill_candidate[regno].reload_slot 
  19450. +                 = SET_SRC (body);
  19451. +               spill_candidate[regno].hard_reg 
  19452. +                 = SET_DEST (body);
  19453. +               spill_candidate[regno].reload_insn = insn;
  19454. +               spill_candidate[regno].mode 
  19455. +                 = GET_MODE (SET_DEST (body));
  19456. +               /* Sanity check */
  19457. +               if (spill_candidate[regno].reload_indx != indx
  19458. +                   && spill_candidate[regno].reload_indx != -1)
  19459. +                 {
  19460. +                   abort ();
  19461. +                 }
  19462. +               spill_candidate[regno].reload_indx = indx;
  19463. +               if (spill_candidate[regno].slot_updated_in_loop == 0)
  19464. +                 {
  19465. +                   spill_candidate[regno].slot_updated_in_loop 
  19466. +                 = reload_slots[indx].reload_slot_updated;
  19467. +                 }
  19468. +               if (spill_candidate[regno].pseudo_reg == 0)
  19469. +                 {
  19470. +                   spill_candidate[regno].disregard = 1;
  19471. +                 }
  19472. +             }
  19473. +         }
  19474. +           if (reload_slots[indx].is_loaded_to_reg == -1)
  19475. +             {
  19476. +               if (reload_slots[indx].reload_stack_mode != -2
  19477. +                   && spill_candidate[regno].disregard == 0)
  19478. +                 {
  19479. +               reload_slots[indx].is_loaded_to_reg = regno;
  19480. +             }
  19481. +         }
  19482. +           else if (regno != reload_slots[indx].is_loaded_to_reg)
  19483. +         {
  19484. +           int loaded_reg;
  19485. +           loaded_reg = reload_slots[indx].is_loaded_to_reg;
  19486. +           /* Same spill slot already loaded to different hard reg */
  19487. +           /* Create a linked list of candidates that load the
  19488. +                      same reload slot */
  19489. +           if (spill_candidate[reload_slots[indx].is_loaded_to_reg].disregard == 0
  19490. +               && GET_MODE (reload_slots[indx].reload_stack_slot) 
  19491. +                 == GET_MODE (SET_SRC (body)))
  19492. +             {
  19493. +               if (spill_candidate[regno].has_link == 0)
  19494. +             {
  19495. +               spill_candidate[regno].has_link = 1;
  19496. +               spill_candidate[loaded_reg].has_link = 1;
  19497. +               spill_candidate[loaded_reg].is_head = 1;
  19498. +               spill_candidate[regno].link_cand 
  19499. +                 = spill_candidate[loaded_reg].link_cand;
  19500. +               spill_candidate[loaded_reg].link_cand 
  19501. +                 = &spill_candidate[regno];
  19502. +               spill_candidate[regno].head_cand 
  19503. +                 = &spill_candidate[loaded_reg];
  19504. +             }
  19505. +             }
  19506. +           else
  19507. +             {
  19508. +               spill_candidate[loaded_reg].disregard = 1;
  19509. +               spill_candidate[regno].disregard = 1;
  19510. +               reload_slots[indx].reload_stack_mode = -2;
  19511. +             }
  19512. +         }
  19513. +         }
  19514. +       else
  19515. +         {
  19516. +           /* reg regno is set to some other value than
  19517. +                  a spill stack slot */
  19518. +           if (!is_updated_by_const (insn))
  19519. +         {
  19520. +           spill_candidate[regno].disregard = 1;
  19521. +           if (spill_candidate[regno].reload_indx != -1)
  19522. +             {
  19523. +               reload_slots[spill_candidate[regno].reload_indx].reload_stack_mode = -2;
  19524. +             }
  19525. +         }
  19526. +           /* It sets it to some other value - signal that by
  19527. +                  the end of this block that value must have been
  19528. +                  stored into the hard registers reload stack slot
  19529. +               */
  19530. +           spill_candidate[regno].must_update_reload = 1;
  19531. +         }
  19532. +     }
  19533. +       else if (is_a_reload_stack_slot (SET_DEST (body), &indx, 0, 0))
  19534. +     { /* This is an update of a reload_stack_slot */
  19535. +       if (GET_CODE (SET_DEST (body)) == SUBREG)
  19536. +         {
  19537. +           reload_slots[indx].reload_stack_mode = -2;
  19538. +         }
  19539. +       reload_slots[indx].reload_slot_updated = 1;
  19540. +       cand_num = reload_slots[indx].is_loaded_to_reg;
  19541. +       /* intel1a */
  19542. +       if (cand_num != -1)
  19543. +         {
  19544. +           spill_candidate[cand_num].slot_updated = 1;
  19545. +         }
  19546. +       if (cand_num == -1)
  19547. +         {
  19548. +           if (!is_updated_by_const_or_reg (insn))
  19549. +         {
  19550. +           /* An update before a load - must not
  19551. +                      become a candidate */
  19552. +           reload_slots[indx].reload_stack_mode = -2;
  19553. +         }
  19554. +         }
  19555. +       else if (GET_CODE (SET_SRC (body)) == REG 
  19556. +            && REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER 
  19557. +            && GET_MODE (SET_SRC (body)) ==
  19558. +            spill_candidate[REGNO (SET_SRC (body))].mode 
  19559. +            && rtx_equal_p (
  19560. +           XEXP (spill_candidate[REGNO (SET_SRC (body))].reload_slot, 0),
  19561. +                  XEXP (SET_DEST (body), 0))
  19562. +         )
  19563. +         {
  19564. +           /* It is an update from the appropriate hard reg
  19565. +                  and was expected */
  19566. +           spill_candidate[cand_num].must_update_reload = 0;
  19567. +           spill_candidate[cand_num].slot_updated_in_loop = 1;
  19568. +         }
  19569. +       else if (spill_candidate[cand_num].must_update_reload != 0)
  19570. +         { /* It was expected to be updated by the hard
  19571. +                  register but it wasn't - the hard register
  19572. +                  that has this as a reload stack slot is no
  19573. +                  longer to be considered a candidate */
  19574. +           spill_candidate[cand_num].disregard = 1;
  19575. +           if (spill_candidate[cand_num].reload_indx != -1)
  19576. +             {
  19577. +           reload_slots[spill_candidate[cand_num].reload_indx].reload_stack_mode = -2;
  19578. +         }
  19579. +         }
  19580. +       else if (!is_updated_by_const_or_reg (insn))
  19581. +         {
  19582. +           spill_candidate[cand_num].disregard = 1;
  19583. +           if (spill_candidate[cand_num].reload_indx != -1)
  19584. +             {
  19585. +           reload_slots[spill_candidate[cand_num].reload_indx].reload_stack_mode = -2;
  19586. +         }
  19587. +         }
  19588. +       else
  19589. +         {
  19590. +           spill_candidate[cand_num].slot_updated_in_loop = 1;
  19591. +         }
  19592. +     }
  19593. +     }
  19594. +   else if (GET_CODE (body) == CLOBBER)
  19595. +     {
  19596. +       if (GET_CODE (SET_DEST (body)) == REG 
  19597. +       && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER)
  19598. +     {
  19599. +       regno = REGNO (SET_DEST (body));
  19600. +       n_regs = HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body)));
  19601. +       for (j = 0; j < n_regs; j++)
  19602. +         {
  19603. +           spill_candidate[regno + j].disregard = 1;
  19604. +           if (spill_candidate[regno + j].reload_indx != -1)
  19605. +             {
  19606. +               reload_slots[spill_candidate[regno + j].
  19607. +                   reload_indx].reload_stack_mode = -2;
  19608. +             }
  19609. +         }
  19610. +     }
  19611. +       else if (GET_CODE (SET_DEST (body)) == SUBREG
  19612. +                && GET_CODE (SUBREG_REG (SET_DEST (body))) == REG 
  19613. +            && REGNO (SUBREG_REG (SET_DEST (body))) < FIRST_PSEUDO_REGISTER)
  19614. +     {
  19615. +       regno = REGNO (SUBREG_REG (SET_DEST (body)));
  19616. +       n_regs 
  19617. +         = max (HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body))),
  19618. +                HARD_REGNO_NREGS (regno, 
  19619. +                                  GET_MODE (SUBREG_REG (SET_DEST (body)))));
  19620. +       for (j = 0; j < n_regs; j++)
  19621. +         {
  19622. +           spill_candidate[regno + j].disregard = 1;
  19623. +           if (spill_candidate[regno + j].reload_indx != -1)
  19624. +             {
  19625. +               reload_slots[spill_candidate[regno + j].
  19626. +                   reload_indx].reload_stack_mode = -2;
  19627. +             }
  19628. +         }
  19629. +     }
  19630. +     }
  19631. +   else if (GET_CODE (body) == PARALLEL)
  19632. +     {
  19633. +       for (i = 0; i < XVECLEN (body, 0); i++)
  19634. +     mark_spill_candidates (insn, XVECEXP (body, 0, i));
  19635. +     }
  19636. +   else
  19637. +     {
  19638. +       all_candidates_invalid = 1;
  19639. +     }
  19640. + }
  19641. + /*
  19642. +   Called to mark cnadidates that are invalid at this point */
  19643. + static
  19644. + void 
  19645. + spill_handle_regs_mentioned (pat)
  19646. +      rtx pat;
  19647. + {
  19648. +   register char *fmt;
  19649. +   register int i;
  19650. +   register enum rtx_code code;
  19651. +   int indx;
  19652. +   code = GET_CODE (pat);
  19653. +   switch (code)
  19654. +     {
  19655. +     case REG:
  19656. +       if (REGNO (pat) < FIRST_PSEUDO_REGISTER)
  19657. +     {
  19658. +       /* intel1a */
  19659. +       if (spill_candidate[REGNO (pat)].slot_updated)
  19660. +         {
  19661. +           spill_candidate[REGNO (pat)].disregard = 1;
  19662. +           for (i=0; i < num_reload_stack_slots; i++)
  19663. +             {
  19664. +               if (reload_slots[i].is_loaded_to_reg == REGNO (pat))
  19665. +                 {
  19666. +                   reload_slots[i].reload_stack_mode = -2;
  19667. +                 }
  19668. +             }
  19669. +         }
  19670. +       if (!spill_candidate[REGNO (pat)].first_set_to_reload)
  19671. +         {
  19672. +           spill_candidate[REGNO (pat)].disregard = 1;
  19673. +           for (i=0; i < num_reload_stack_slots; i++)
  19674. +             {
  19675. +               if (reload_slots[i].is_loaded_to_reg == REGNO (pat))
  19676. +                 {
  19677. +                   reload_slots[i].reload_stack_mode = -2;
  19678. +                 }
  19679. +             }
  19680. +         }
  19681. +     }
  19682. +       return;
  19683. +       /* These codes have no constituent expressions
  19684. +      and are unique.  */
  19685. +     case SCRATCH:
  19686. +     case CC0:
  19687. +     case PC:
  19688. +     case QUEUED:
  19689. +     case CONST_INT:
  19690. +     case CONST_DOUBLE:
  19691. +     case SYMBOL_REF:
  19692. +     case CODE_LABEL:
  19693. +       return;
  19694. +     }
  19695. +   /* The reload stack slot must always be accessed in the same mode */
  19696. +   if ((GET_CODE (pat) == MEM || GET_CODE (pat) == SUBREG)
  19697. +       && is_a_reload_stack_slot (pat, &indx, 0, 0))
  19698. +     {
  19699. +       if (GET_CODE (pat) == SUBREG)
  19700. +         {
  19701. +       /* Signal invalid */
  19702. +       reload_slots[indx].reload_stack_mode = -2;
  19703. +         }
  19704. +       else if (reload_slots[indx].reload_stack_mode == -1)
  19705. +     {
  19706. +       reload_slots[indx].reload_stack_mode = GET_MODE (pat);
  19707. +     }
  19708. +       else if (reload_slots[indx].reload_stack_mode != GET_MODE (pat))
  19709. +     {
  19710. +       /* Signal invalid */
  19711. +       reload_slots[indx].reload_stack_mode = -2;
  19712. +     }
  19713. +     }
  19714. +   fmt = GET_RTX_FORMAT (code);
  19715. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  19716. +     {
  19717. +       if (fmt[i] == 'E')
  19718. +     {
  19719. +       register int j;
  19720. +       for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
  19721. +         spill_handle_regs_mentioned (XVECEXP (pat, i, j));
  19722. +     }
  19723. +       else if (fmt[i] == 'e')
  19724. +     spill_handle_regs_mentioned (XEXP (pat, i));
  19725. +     }
  19726. + }
  19727. + /*
  19728. +   Return 1 if insn updates a value by a constant value */
  19729. + static
  19730. + int 
  19731. + is_updated_by_const (insn)
  19732. +      rtx insn;
  19733. + {
  19734. +   if (GET_CODE (PATTERN (insn)) != SET)
  19735. +     {
  19736. +       return (0);
  19737. +     }
  19738. +   if (GET_RTX_LENGTH (GET_CODE (SET_SRC (PATTERN (insn)))) != 2)
  19739. +     {
  19740. +       return (0);
  19741. +     }
  19742. +   if (!rtx_equal_p (XEXP (SET_SRC (PATTERN (insn)), 0),
  19743. +             SET_DEST (PATTERN (insn))))
  19744. +     {
  19745. +       return (0);
  19746. +     }
  19747. +   if (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) != CONST_INT)
  19748. +     {
  19749. +       return (0);
  19750. +     }
  19751. +   return (1);
  19752. + }
  19753. + /*
  19754. +   Return 1 if insn updates a value by a constant value or register */
  19755. + static
  19756. + int 
  19757. + is_updated_by_const_or_reg (insn)
  19758. +      rtx insn;
  19759. + {
  19760. +   if (GET_CODE (PATTERN (insn)) != SET)
  19761. +     {
  19762. +       return (0);
  19763. +     }
  19764. +   if (GET_RTX_LENGTH (GET_CODE (SET_SRC (PATTERN (insn)))) != 2)
  19765. +     {
  19766. +       return (0);
  19767. +     }
  19768. +   if (!rtx_equal_p (XEXP (SET_SRC (PATTERN (insn)), 0),
  19769. +             SET_DEST (PATTERN (insn))))
  19770. +     {
  19771. +       return (0);
  19772. +     }
  19773. +   if (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) != CONST_INT
  19774. +       && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) != REG)
  19775. +     {
  19776. +       return (0);
  19777. +     }
  19778. +   return (1);
  19779. + }
  19780. + /* Go over the whole function and do
  19781. +    spill_slotA <- regY                     spill_slotA <- regY
  19782. +         .  sequence of code not                 .  sequence of code not
  19783. +         .  affecting regY or       =>           .  affecting regY or
  19784. +         .  spill_slotA                          .  spill_slotA
  19785. +    regX <- spill_slotA                     regX <- regY
  19786. + */
  19787. + void 
  19788. + peep_spills (f, dumpfile)
  19789. +      rtx f;
  19790. +      FILE * dumpfile;
  19791. + {
  19792. +   rtx insn, next, note;
  19793. +   int i, indx, insn_code_number, success;
  19794. +   undobuf.num_undo = 0;
  19795. +   num_reload_stack_slots = 0;
  19796. +   cur_stack_offset = 0;
  19797. +   bzero (spill_candidate, FIRST_PSEUDO_REGISTER * sizeof (spill_candidate[0]));
  19798. +   loop_dump_stream = dumpfile;
  19799. +   if (loop_dump_stream)
  19800. +     {
  19801. +       fprintf (loop_dump_stream, "\n\nDoing peep spills\n\n");
  19802. +     }
  19803. +   insn = f;
  19804. +   while (insn)
  19805. +     {
  19806. +       if (GET_CODE (insn) == INSN && RTX_IS_SPILL_P (insn) 
  19807. +       && GET_CODE (SET_SRC (PATTERN (insn))) == MEM 
  19808. +       && is_a_stack_slot (SET_SRC (PATTERN (insn)))
  19809. +       && !is_a_reload_stack_slot (SET_SRC (PATTERN (insn)), &indx,
  19810. +                                   cur_stack_offset, 0) )
  19811. +     {    
  19812. +       if (num_reload_stack_slots >= MAX_RELOAD_STACK_SLOTS)
  19813. +         {
  19814. +           return;
  19815. +         }
  19816. +       if (loop_dump_stream)
  19817. +         {
  19818. +           fprintf (loop_dump_stream, "reload slot at insn %d offset %d %d %d\n",
  19819. +           INSN_UID (insn), cur_stack_offset,
  19820. +           RTX_IS_SPILL_P (SET_SRC (PATTERN (insn))),
  19821. +           RTX_IS_SPILL_P (XEXP (SET_SRC (PATTERN (insn)), 0)));
  19822. +         }
  19823. +       reload_slots[num_reload_stack_slots].is_loaded_to_reg = -1;
  19824. +       reload_slots[num_reload_stack_slots].last_store = NULL;
  19825. +       reload_slots[num_reload_stack_slots].cur_stack_offset 
  19826. +         = cur_stack_offset;
  19827. +       reload_slots[num_reload_stack_slots].reload_stack_slot 
  19828. +         = SET_SRC (PATTERN (insn));
  19829. +       reload_slots[num_reload_stack_slots++].reload_insn = insn; 
  19830. +     }
  19831. +       else if (GET_CODE (insn) == INSN && RTX_IS_SPILL_P (insn) 
  19832. +       && GET_CODE (SET_DEST (PATTERN (insn))) == MEM 
  19833. +       && is_a_stack_slot (SET_DEST (PATTERN (insn)))
  19834. +       && !is_a_reload_stack_slot (SET_DEST (PATTERN (insn)), &indx,
  19835. +                                   cur_stack_offset, 0) )
  19836. +     {    
  19837. +       if (num_reload_stack_slots >= MAX_RELOAD_STACK_SLOTS)
  19838. +         {
  19839. +           return;
  19840. +         }
  19841. +       if (loop_dump_stream)
  19842. +         {
  19843. +           fprintf (loop_dump_stream, "reload slot at insn %d offset %d\n",
  19844. +           INSN_UID (insn), cur_stack_offset);
  19845. +         }
  19846. +       reload_slots[num_reload_stack_slots].is_loaded_to_reg = -1;
  19847. +       reload_slots[num_reload_stack_slots].last_store = NULL;
  19848. +       reload_slots[num_reload_stack_slots].cur_stack_offset 
  19849. +         = cur_stack_offset;
  19850. +       reload_slots[num_reload_stack_slots].reload_stack_slot 
  19851. +         = SET_DEST (PATTERN (insn));
  19852. +       reload_slots[num_reload_stack_slots++].reload_insn = insn; 
  19853. +     }
  19854. +       if (GET_CODE (insn) == INSN)
  19855. +     {
  19856. +       if (GET_CODE (PATTERN (insn)) == SET)
  19857. +         update_stack_offset (PATTERN (insn), &cur_stack_offset);
  19858. +       else if (GET_CODE (PATTERN (insn)) == PARALLEL)
  19859. +         {
  19860. +           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
  19861. +         update_stack_offset (XVECEXP (PATTERN (insn), 0, i), 
  19862. +                              &cur_stack_offset);
  19863. +         }
  19864. +     }
  19865. +       insn = NEXT_INSN (insn);
  19866. +     }
  19867. +   cur_stack_offset = 0;
  19868. +   insn = f;
  19869. +   while (insn)
  19870. +     {
  19871. +       if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
  19872. +     {
  19873. +       spill_peep_insn (insn, PATTERN (insn));
  19874. +       if (have_flow_analysis 
  19875. +         && GET_CODE (PATTERN (insn)) == SET
  19876. +         && GET_CODE (SET_DEST (PATTERN (insn))) == REG
  19877. +         && GET_CODE (SET_SRC (PATTERN (insn))) == REG
  19878. +         && (next = next_nonnote_insn (insn))
  19879. +         && GET_CODE (next) == INSN
  19880. +         && GET_CODE (next) == INSN
  19881. +         && (note = find_regno_note (next, 
  19882. +                             REG_DEAD, 
  19883. +                             REGNO (SET_DEST (PATTERN (insn)))))
  19884. +         && rtx_equal_p (XEXP (note, 0), SET_DEST (PATTERN (insn)))
  19885. +          )
  19886. +             { /* we have reg1 <- reg2 and reg1 dead in next insn
  19887. +               replace reg1 with reg2 in next insn and delete this
  19888. +               insn */
  19889. +               init_undo_buf ();
  19890. +               subst_in_insn (next,
  19891. +                              PATTERN (next),
  19892. +                              SET_DEST (PATTERN (insn)),
  19893. +                              SET_SRC (PATTERN (insn)),
  19894. +                              0,
  19895. +                              0);
  19896. +               if (reg_overlap_mentioned_p (XEXP (note, 0), PATTERN (next))
  19897. +                   || (insn_code_number = recog (PATTERN (next), next, 0)) < 0)
  19898. +                 {
  19899. +                   loop_undo_all ();
  19900. +                   success = 0;
  19901. +                 }
  19902. +               else
  19903. +                 {
  19904. +                   success = 1;
  19905. + #ifdef REGISTER_CONSTRAINTS
  19906. +                   INSN_CODE (next) = insn_code_number;
  19907. +                   insn_extract (next);
  19908. +                   if (!constrain_operands (insn_code_number, 1))
  19909. +                     {
  19910. +                       loop_undo_all ();
  19911. +                       INSN_CODE (next) 
  19912. +                         = recog (PATTERN (next), 
  19913. +                                  next, 0);
  19914. +                       success = 0;
  19915. +                     }
  19916. + #endif
  19917. +                   if (success)
  19918. +                     {
  19919. +                       if (loop_dump_stream)
  19920. +                         {
  19921. +                           fprintf (loop_dump_stream,
  19922. +                           "replace reg %d with reg %d in insn %d, delete insn %d\n",
  19923. +                           REGNO (SET_DEST (PATTERN (insn))),
  19924. +                           REGNO (SET_SRC (PATTERN (insn))),
  19925. +                           INSN_UID (next), INSN_UID (insn));
  19926. +                         }
  19927. +               PUT_CODE (insn, NOTE);
  19928. +               NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
  19929. +               NOTE_SOURCE_FILE (insn) = 0;
  19930. +               remove_note (next, note);
  19931. +                     }
  19932. +                 }
  19933. +             }
  19934. +         }
  19935. +       else if (GET_CODE (insn) == CODE_LABEL)
  19936. +     {
  19937. +       peep_init_info ();
  19938. +     }
  19939. +       insn = NEXT_INSN (insn);
  19940. +     }
  19941. +   have_flow_analysis = 0;
  19942. + }
  19943. + static
  19944. + void 
  19945. + peep_init_info ()
  19946. + {
  19947. +   int i;
  19948. +   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  19949. +     {
  19950. +       spill_candidate[i].reload_slot = 0;
  19951. +       spill_candidate[i].disregard = 0;
  19952. +     }
  19953. +   for (i=0; i < num_reload_stack_slots; i++)
  19954. +     {
  19955. +       reload_slots[i].is_loaded_to_reg = -1;
  19956. +       reload_slots[i].last_store = NULL;
  19957. +     }
  19958. + }
  19959. + /*
  19960. +   In body of insn replace any reload stack slots with registers that
  19961. +   have the same value
  19962. + */
  19963. + static
  19964. + void 
  19965. + spill_peep_insn (insn, body)
  19966. +      rtx insn;
  19967. +      rtx body;
  19968. + {
  19969. +   enum rtx_code code;
  19970. +   int i, j, indx, regno, cand_num, insn_code_number, cur_code_number, success,
  19971. +       n_regs;
  19972. +   undobuf.num_undo = 0;
  19973. +   code = GET_CODE (body);
  19974. +   if (code == SET)
  19975. +     {
  19976. +     
  19977. +       if (/*cur_stack_offset == 0*/ 1)
  19978. +     {
  19979. +       if (GET_CODE (SET_SRC (body)) == MEM 
  19980. +           && is_a_reload_stack_slot (SET_SRC (body), &indx, cur_stack_offset, 0))
  19981. +         {
  19982. +           cand_num = reload_slots[indx].is_loaded_to_reg;
  19983. +           if (cand_num != -1 && spill_candidate[cand_num].disregard == 0 
  19984. +           && spill_candidate[cand_num].reload_slot 
  19985. +           && GET_MODE (spill_candidate[cand_num].reload_slot)
  19986. +                == GET_MODE (SET_SRC (body))
  19987. +           && are_same_reload_slots (spill_candidate[cand_num].reload_slot,
  19988. +                        spill_candidate[cand_num].cur_stack_offset,
  19989. +                    SET_SRC (body), cur_stack_offset))
  19990. +         {
  19991. +           SET_SRC (body) = spill_candidate[cand_num].hard_reg;
  19992. +           if ((insn_code_number = recog (PATTERN (insn), insn, 0)) < 0)
  19993. +             {
  19994. +               SET_SRC (body) = spill_candidate[cand_num].reload_slot;
  19995. +             }
  19996. +           else
  19997. +             {
  19998. +               success = 1;
  19999. + #ifdef REGISTER_CONSTRAINTS
  20000. +               INSN_CODE (insn) = insn_code_number;
  20001. +               insn_extract (insn);
  20002. +               if (!constrain_operands (insn_code_number, 1))
  20003. +             {
  20004. +               SET_SRC (body) 
  20005. +                 = spill_candidate[cand_num].reload_slot;
  20006. +               INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
  20007. +               success = 0;
  20008. +             }
  20009. + #endif
  20010. +               if (success && loop_dump_stream)
  20011. +             {
  20012. +               fprintf (loop_dump_stream,
  20013. +                  " replacing stack slot (src) with reg%d in insn %d\n",
  20014. +                    REGNO (spill_candidate[cand_num].hard_reg), INSN_UID (insn));
  20015. +             }
  20016. +             }
  20017. +         }
  20018. +         }
  20019. +       else
  20020. +         {
  20021. +               undobuf.storage = (char *) oballoc (0);
  20022. +           replace_spill_slots (insn, SET_SRC (body), &SET_SRC (body));
  20023. +           if (undobuf.num_undo)
  20024. +             {
  20025. +           if ((insn_code_number = recog (PATTERN (insn), insn, 0)) < 0)
  20026. +             {
  20027. +               loop_undo_all ();
  20028. +               if (loop_dump_stream)
  20029. +             {
  20030. +                fprintf (loop_dump_stream, "  replacment did not succeed %d\n", INSN_UID (insn));
  20031. +             }
  20032. +             }
  20033. + #ifdef REGISTER_CONSTRAINTS
  20034. +           else
  20035. +             {
  20036. +               INSN_CODE (insn) = insn_code_number;
  20037. +               insn_extract (insn);
  20038. +               if (!constrain_operands (insn_code_number, 1))
  20039. +             {
  20040. +               loop_undo_all ();
  20041. +                   INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
  20042. +               if (loop_dump_stream)
  20043. +                 {
  20044. +                   fprintf (loop_dump_stream, "  replacment did not succeed %d\n", INSN_UID (insn));
  20045. +                 }
  20046. +             }
  20047. +             }
  20048. + #endif
  20049. +                   undobuf.num_undo = 0;
  20050. +                 }
  20051. +         }
  20052. +     }
  20053. +       if (GET_CODE (SET_DEST (body)) == REG
  20054. +       && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER)
  20055. +     {
  20056. +       regno = REGNO (SET_DEST (body));
  20057. +       if (HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body))) > 1)
  20058. +         {
  20059. +           regno = REGNO (SET_DEST (body));
  20060. +           n_regs = HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body)));
  20061. +           for (j = 0; j < n_regs; j++)
  20062. +             {
  20063. +               spill_candidate[regno + j].disregard = 1;
  20064. +                   spill_candidate[regno + j].reload_slot = NULL;
  20065. +                   for (i=0; i < num_reload_stack_slots; i++)
  20066. +                     {
  20067. +                       if (reload_slots[i].is_loaded_to_reg == regno + i)
  20068. +                         {
  20069. +                           reload_slots[i].is_loaded_to_reg = -1;
  20070. +                         }
  20071. +                     }
  20072. +             }
  20073. +         }
  20074. +       if (GET_CODE (SET_SRC (body)) == MEM 
  20075. +           && is_a_reload_stack_slot (SET_SRC (body), &indx, cur_stack_offset, 0) 
  20076. +           && HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body))) == 1)
  20077. +         { /* It sets it to the value in a reload stack slot */
  20078. +           spill_candidate[regno].reload_slot = SET_SRC (body);
  20079. +           spill_candidate[regno].hard_reg = SET_DEST (body);
  20080. +           spill_candidate[regno].disregard = 0;
  20081. +           spill_candidate[regno].reload_insn = insn;
  20082. +           spill_candidate[regno].cur_stack_offset = cur_stack_offset;
  20083. +               reload_slots[indx].last_store = NULL;
  20084. +           reload_slots[indx].is_loaded_to_reg = regno;
  20085. +         }
  20086. +       else
  20087. +         {
  20088. +           spill_candidate[regno].disregard = 1;
  20089. +           spill_candidate[regno].reload_slot = NULL;
  20090. +           for (i=0; i < num_reload_stack_slots; i++)
  20091. +             {
  20092. +               if (reload_slots[i].is_loaded_to_reg == regno)
  20093. +                 {
  20094. +                   reload_slots[i].is_loaded_to_reg = -1;
  20095. +                 }
  20096. +             }
  20097. +         }
  20098. +     }
  20099. +       else if (GET_CODE (SET_DEST (body)) == SUBREG
  20100. +                && GET_CODE (SUBREG_REG (SET_DEST (body))) == REG
  20101. +            && REGNO (SUBREG_REG (SET_DEST (body))) < FIRST_PSEUDO_REGISTER)
  20102. +     { /* Simple handling of subregs - invalidate the subreg being set */
  20103. +       regno = REGNO (SUBREG_REG (SET_DEST (body)));
  20104. +       n_regs = HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body)));
  20105. +       for (j = 0; j < n_regs; j++)
  20106. +         {
  20107. +           spill_candidate[regno + j].disregard = 1;
  20108. +               spill_candidate[regno + j].reload_slot = NULL;
  20109. +               for (i=0; i < num_reload_stack_slots; i++)
  20110. +                 {
  20111. +                   if (reload_slots[i].is_loaded_to_reg == regno + i)
  20112. +                     {
  20113. +                       reload_slots[i].is_loaded_to_reg = -1;
  20114. +                     }
  20115. +                 }
  20116. +         }
  20117. +     }
  20118. +       else if (is_a_reload_stack_slot (SET_DEST (body), &indx, cur_stack_offset, 0))
  20119. +     { /* This is an update of a reload_stack_slot */
  20120. +               /* Check if last write into this reload slot can be deleted */
  20121. +               if (reload_slots[indx].last_store
  20122. +                   && GET_CODE (SET_DEST (body)) != SUBREG
  20123. +                   /* && GET_CODE (SET_SRC (body)) == REG */
  20124. +           && REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER
  20125. +                && GET_MODE (SET_DEST ( PATTERN (reload_slots[indx].last_store)))
  20126. +                   == GET_MODE (SET_DEST (body))
  20127. +                   && spill_slot_unused_between (
  20128. +                       SET_DEST ( PATTERN (reload_slots[indx].last_store)),
  20129. +                       reload_slots[indx].last_store, insn))
  20130. +                 {
  20131. +                   if (loop_dump_stream)
  20132. +                     {
  20133. +                       fprintf (loop_dump_stream, "delete redundant spill store at %d becuase of re-store at %d\n",
  20134. +                                INSN_UID (reload_slots[indx].last_store),
  20135. +                                INSN_UID (insn));
  20136. +                     }
  20137. +           PUT_CODE (reload_slots[indx].last_store, NOTE);
  20138. +           NOTE_LINE_NUMBER (reload_slots[indx].last_store) = NOTE_INSN_DELETED;
  20139. +           NOTE_SOURCE_FILE (reload_slots[indx].last_store) = 0;
  20140. +           reload_slots[indx].is_loaded_to_reg = -1;
  20141. +           reload_slots[indx].last_store = NULL;
  20142. +                  }
  20143. +           if (GET_CODE (SET_SRC (body)) == REG 
  20144. +                   && GET_CODE (SET_DEST (body)) != SUBREG
  20145. +               &&HARD_REGNO_NREGS(REGNO(SET_SRC(body)),
  20146. +                       GET_MODE(SET_DEST(body))) == 1
  20147. +           && REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER)
  20148. +         {
  20149. +           regno = REGNO (SET_SRC (body));
  20150. +           spill_candidate[regno].reload_slot = SET_DEST (body);
  20151. +           spill_candidate[regno].hard_reg = SET_SRC (body);
  20152. +           spill_candidate[regno].disregard = 0;
  20153. +           spill_candidate[regno].reload_insn = insn;
  20154. +               spill_candidate[regno].cur_stack_offset = cur_stack_offset;
  20155. +               reload_slots[indx].last_store = insn;
  20156. +           reload_slots[indx].is_loaded_to_reg = regno;
  20157. +         }
  20158. +           else
  20159. +             {
  20160. +                   regno = reload_slots[indx].is_loaded_to_reg;
  20161. +                   if (regno != -1)
  20162. +                     { /* This candidate is now invalid */
  20163. +                spill_candidate[regno].disregard = 1;
  20164. +                spill_candidate[regno].reload_slot = NULL;
  20165. +                     }
  20166. +           reload_slots[indx].is_loaded_to_reg = -1;
  20167. +           reload_slots[indx].last_store = NULL;
  20168. +             }
  20169. +     }
  20170. +       update_stack_offset (body, &cur_stack_offset);
  20171. +     }
  20172. +   else if (code == CLOBBER)
  20173. +     {
  20174. +       if (GET_CODE (SET_DEST (body)) == REG 
  20175. +       && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER)
  20176. +     {
  20177. +       regno = REGNO (SET_DEST (body));
  20178. +       n_regs = HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body)));
  20179. +       for (j = 0; j < n_regs; j++)
  20180. +         {
  20181. +           spill_candidate[regno + j].disregard = 1;
  20182. +           for (i=0; i < num_reload_stack_slots; i++)
  20183. +             {
  20184. +               if (reload_slots[i].is_loaded_to_reg == (regno + j))
  20185. +                 {
  20186. +                   reload_slots[i].is_loaded_to_reg = -1;
  20187. +                 }
  20188. +             }
  20189. +         }
  20190. +     }
  20191. +       else if (GET_CODE (SET_DEST (body)) == SUBREG
  20192. +                && GET_CODE (SUBREG_REG (SET_DEST (body))) == REG 
  20193. +            && REGNO (SUBREG_REG (SET_DEST (body))) < FIRST_PSEUDO_REGISTER)
  20194. +     {
  20195. +       regno = REGNO (SUBREG_REG (SET_DEST (body)));
  20196. +       n_regs 
  20197. +         = max (HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body))),
  20198. +                HARD_REGNO_NREGS (regno, 
  20199. +                                  GET_MODE (SUBREG_REG (SET_DEST (body)))));
  20200. +       for (j = 0; j < n_regs; j++)
  20201. +         {
  20202. +           spill_candidate[regno + j].disregard = 1;
  20203. +           for (i=0; i < num_reload_stack_slots; i++)
  20204. +             {
  20205. +               if (reload_slots[i].is_loaded_to_reg == (regno + j))
  20206. +                 {
  20207. +                   reload_slots[i].is_loaded_to_reg = -1;
  20208. +                 }
  20209. +             }
  20210. +         }
  20211. +     }
  20212. +       else if (is_a_reload_stack_slot (SET_DEST (body), &indx, cur_stack_offset, 0))
  20213. +         {
  20214. +           regno = reload_slots[indx].is_loaded_to_reg;
  20215. +           if (regno != -1)
  20216. +             { /* This candidate is now invalid */
  20217. +         spill_candidate[regno].disregard = 1;
  20218. +         spill_candidate[regno].reload_slot = NULL;
  20219. +         }
  20220. +           reload_slots[indx].is_loaded_to_reg = -1;
  20221. +       reload_slots[indx].last_store = NULL;
  20222. +         }
  20223. +     }
  20224. +   if (code == PARALLEL)
  20225. +     {
  20226. +       for (i = 0; i < XVECLEN (body, 0); i++)
  20227. +     spill_peep_insn (insn, XVECEXP (body, 0, i));
  20228. +     }
  20229. +   if (GET_CODE (insn) == CALL_INSN)
  20230. +     { /* All call clobbered registers are no longer valid */
  20231. +       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  20232. +     {
  20233. +       if (call_used_regs[i])
  20234. +         {
  20235. +           spill_candidate[i].disregard = 1;
  20236. +           for (j=0; j < num_reload_stack_slots; j++)
  20237. +             {
  20238. +               if (reload_slots[j].is_loaded_to_reg == i)
  20239. +                 {
  20240. +                   reload_slots[j].is_loaded_to_reg = -1;
  20241. +                 }
  20242. +             }
  20243. +         }
  20244. +     }
  20245. +     }
  20246. + }
  20247. + /*
  20248. +   Return 1 iff we are sure that the spill_slot  (or any subpart of it)
  20249. +   is not refernced between start and end.  Also there must be no 
  20250. +   CALL JUMP or LABELs in between them
  20251. + */
  20252. + static
  20253. + int
  20254. + spill_slot_unused_between (spill_slot, start, end)
  20255. +   rtx spill_slot, start, end;
  20256. + {
  20257. +   rtx tinsn;
  20258. +   int mcur_stack_offset = 0;
  20259. +   for (tinsn = next_nonnote_insn (start);
  20260. +        tinsn && tinsn != end;
  20261. +        tinsn = next_nonnote_insn (tinsn))
  20262. +     {
  20263. +       if (GET_CODE (tinsn) == CALL_INSN || GET_CODE (tinsn) == JUMP_INSN 
  20264. +           || GET_CODE (tinsn) == CODE_LABEL)
  20265. +         {
  20266. +           return (0);
  20267. +         }
  20268. +       if (spill_slot_mentioned(spill_slot, PATTERN (tinsn), mcur_stack_offset))
  20269. +         {
  20270. +           return (0);
  20271. +         }
  20272. +       update_stack_offset (PATTERN (tinsn), &mcur_stack_offset);
  20273. +     }
  20274. +   return (1);
  20275. + }
  20276. + /*
  20277. +   Return 1 if spill_slot or any part of it is mentioned in pat.
  20278. +   relative_stack_offset is the offset of the stack pointer relative
  20279. +   to the point at which spill_slot was stored into.  
  20280. + */
  20281. + static int
  20282. + spill_slot_mentioned (spill_slot, pat, relative_stack_offset)
  20283. +      rtx pat, spill_slot;
  20284. +      int relative_stack_offset;
  20285. + {
  20286. +   register char *fmt;
  20287. +   register int i;
  20288. +   register enum rtx_code code;
  20289. +   code = GET_CODE (pat);
  20290. +   switch (code)
  20291. +     {
  20292. +       /* These codes have no constituent expressions
  20293. +      and are unique.  */
  20294. +     case REG:
  20295. +     case SCRATCH:
  20296. +     case CC0:
  20297. +     case PC:
  20298. +     case QUEUED:
  20299. +     case CONST_INT:
  20300. +     case CONST_DOUBLE:
  20301. +     case SYMBOL_REF:
  20302. +     case CODE_LABEL:
  20303. +       return (0);
  20304. +     case MEM:
  20305. +       if (is_a_stack_slot (pat)
  20306. +           && are_same_reload_slots (spill_slot, 0, pat, relative_stack_offset))
  20307. +         {
  20308. +           return (1);
  20309. +         }
  20310. +       return (0);
  20311. +     }
  20312. +   fmt = GET_RTX_FORMAT (code);
  20313. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  20314. +     {
  20315. +       if (fmt[i] == 'E')
  20316. +     {
  20317. +       register int j;
  20318. +       for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
  20319. +         if (spill_slot_mentioned (spill_slot, XVECEXP (pat, i, j),
  20320. +                                   relative_stack_offset))
  20321. +           {
  20322. +             return (1);
  20323. +           }
  20324. +     }
  20325. +       else if (fmt[i] == 'e')
  20326. +     if (spill_slot_mentioned (spill_slot, XEXP (pat, i),
  20327. +                                   relative_stack_offset))
  20328. +       {
  20329. +         return (1);
  20330. +       }
  20331. +     }
  20332. +   return (0);
  20333. + }
  20334. + /*
  20335. +   Keep track of the depth of the stack
  20336. + */
  20337. + /* static */
  20338. + void 
  20339. + update_stack_offset (pat, addr_stack_offset)
  20340. +      rtx pat;
  20341. +      int *addr_stack_offset;
  20342. + {
  20343. +   int i;
  20344. +   if (GET_CODE (pat) != SET)
  20345. +     {
  20346. +       return;
  20347. +     }
  20348. +   if (GET_CODE (SET_DEST (pat)) == REG
  20349. +       && XINT (SET_DEST (pat), 0) == STACK_POINTER_REGNUM
  20350. +       && GET_CODE (SET_SRC (pat)) == PLUS
  20351. +       && GET_CODE (XEXP (SET_SRC (pat), 0)) == REG
  20352. +       && XINT (XEXP (SET_SRC (pat), 0), 0) == STACK_POINTER_REGNUM)
  20353. +     {
  20354. +       *addr_stack_offset -= XINT (XEXP (SET_SRC (pat), 1), 0);
  20355. +     }
  20356. +   else if (GET_CODE (SET_DEST (pat)) == MEM 
  20357. +        && GET_CODE (XEXP (SET_DEST (pat), 0)) == PRE_DEC
  20358. +        && XEXP (XEXP (SET_DEST (pat), 0), 0) == stack_pointer_rtx)
  20359. +     {
  20360. +       spill_candidate[STACK_POINTER_REGNUM].disregard = 1;
  20361. +       for (i=0; i < num_reload_stack_slots; i++)
  20362. +     {
  20363. +       if (reload_slots[i].is_loaded_to_reg == STACK_POINTER_REGNUM)
  20364. +         {
  20365. +           reload_slots[i].is_loaded_to_reg = -1;
  20366. +         }
  20367. +     }
  20368. +       *addr_stack_offset += GET_MODE_SIZE (GET_MODE (SET_DEST (pat)));
  20369. +     }
  20370. +   else if (GET_CODE (SET_DEST (pat)) == MEM 
  20371. +        && GET_CODE (XEXP (SET_DEST (pat), 0)) == PRE_INC
  20372. +        && XEXP (XEXP (SET_DEST (pat), 0), 0) == stack_pointer_rtx)
  20373. +     {
  20374. +       spill_candidate[STACK_POINTER_REGNUM].disregard = 1;
  20375. +       for (i=0; i < num_reload_stack_slots; i++)
  20376. +     {
  20377. +       if (reload_slots[i].is_loaded_to_reg == STACK_POINTER_REGNUM)
  20378. +         {
  20379. +           reload_slots[i].is_loaded_to_reg = -1;
  20380. +         }
  20381. +     }
  20382. +       *addr_stack_offset -= GET_MODE_SIZE (GET_MODE (SET_DEST (pat)));
  20383. +     }
  20384. + }
  20385. + /*
  20386. +   Replace stack spill slots in pat of insn with the appropriate spill
  20387. +   candidate
  20388. + */
  20389. + static
  20390. + void
  20391. + replace_spill_slots (insn, pat, where)
  20392. +      rtx insn;
  20393. +      rtx pat;
  20394. +      rtx *where;
  20395. + {
  20396. +   register RTX_CODE code = GET_CODE (pat);
  20397. +   register int i, j;
  20398. +   register char *fmt;
  20399. +   int cand_num, indx;
  20400. +   rtx note;
  20401. +   switch (code)
  20402. +     {
  20403. +     case HIGH:
  20404. +     case CONST_INT:
  20405. +     case CONST:
  20406. +     case CONST_DOUBLE:
  20407. +     case SYMBOL_REF:
  20408. +     case LABEL_REF:
  20409. +     case PC:
  20410. +     case CC0:
  20411. +     case REG:
  20412. +       return;
  20413. +     default:
  20414. +       break;
  20415. +     }
  20416. +   if (GET_CODE (pat) == MEM && is_a_reload_stack_slot (pat, &indx, cur_stack_offset, 0))
  20417. +     {
  20418. +       cand_num = reload_slots[indx].is_loaded_to_reg;
  20419. +       if (cand_num != -1 && spill_candidate[cand_num].disregard == 0 
  20420. +       && spill_candidate[cand_num].reload_slot 
  20421. +       && GET_MODE (spill_candidate[cand_num].reload_slot)
  20422. +            == GET_MODE (pat)
  20423. +       && are_same_reload_slots (spill_candidate[cand_num].reload_slot,
  20424. +                                 spill_candidate[cand_num].cur_stack_offset,
  20425. +                                 pat, cur_stack_offset))
  20426. +     {
  20427. +       note = find_reg_note (spill_candidate[cand_num].reload_insn,
  20428. +                 REG_DEAD,
  20429. +                 spill_candidate[cand_num].hard_reg);
  20430. +       if (note)
  20431. +         {
  20432. +           remove_note (spill_candidate[cand_num].reload_insn, note);
  20433. +         }
  20434. +       if (loop_dump_stream)
  20435. +         {
  20436. +           fprintf (loop_dump_stream, " replacing stack slot with reg%d in insn %d\n",
  20437. +            REGNO (spill_candidate[cand_num].hard_reg), INSN_UID (insn));
  20438. +         }
  20439. +       LOOP_SUBST (where, spill_candidate[cand_num].hard_reg);
  20440. +     }
  20441. +     }
  20442. +   fmt = GET_RTX_FORMAT (code);
  20443. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  20444. +     if (fmt[i] == 'e')
  20445. +       replace_spill_slots (insn, XEXP (pat, i), &XEXP (pat, i));
  20446. +     else if (fmt[i] == 'E' || fmt[i] == 'V')
  20447. +       {
  20448. +     for (j = 0; j < XVECLEN (pat, i); j++)
  20449. +       replace_spill_slots (insn, XVECEXP (pat, i, j), &XVECEXP (pat, i, j));
  20450. +       }
  20451. + }
  20452. + /*
  20453. +   Replace any hard registers in pat of insn, that are on a linked
  20454. +   list of spill candidates, with the head candidate of the list
  20455. + */
  20456. + static
  20457. + rtx 
  20458. + replace_linked_regs (insn, pat)
  20459. +      rtx insn;
  20460. +      rtx pat;
  20461. + {
  20462. +   register RTX_CODE code = GET_CODE (pat);
  20463. +   register int i, j;
  20464. +   register char *fmt;
  20465. +   int cand_num, indx;
  20466. +   rtx note;
  20467. +   switch (code)
  20468. +     {
  20469. +     case HIGH:
  20470. +     case CONST_INT:
  20471. +     case CONST:
  20472. +     case CONST_DOUBLE:
  20473. +     case SYMBOL_REF:
  20474. +     case LABEL_REF:
  20475. +     case PC:
  20476. +     case CC0:
  20477. +       return pat;
  20478. +     case REG:
  20479. +       if (spill_candidate[REGNO (pat)].head_cand 
  20480. +       && (spill_candidate[REGNO (pat)].head_cand)->disregard == 0)
  20481. +     {
  20482. +       if (loop_dump_stream)
  20483. +         {
  20484. +           fprintf (loop_dump_stream, " replacing reg%d with reg%d in insn %d\n",
  20485. +                REGNO (pat),
  20486. +          REGNO ((spill_candidate[REGNO (pat)].head_cand)->hard_reg),
  20487. +                INSN_UID (insn));
  20488. +         }
  20489. +       return ((spill_candidate[REGNO (pat)].head_cand)->hard_reg);
  20490. +     }
  20491. +       else
  20492. +     return pat;
  20493. +     default:
  20494. +       break;
  20495. +     }
  20496. +   fmt = GET_RTX_FORMAT (code);
  20497. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  20498. +     if (fmt[i] == 'e')
  20499. +       XEXP (pat, i) = replace_linked_regs (insn, XEXP (pat, i));
  20500. +     else if (fmt[i] == 'E' || fmt[i] == 'V')
  20501. +       {
  20502. +     for (j = 0; j < XVECLEN (pat, i); j++)
  20503. +       XVECEXP (pat, i, j) 
  20504. +         = replace_linked_regs (insn, XVECEXP (pat, i, j));
  20505. +       }
  20506. +   return pat;
  20507. + }
  20508. + /*
  20509. +   Mark all registers mentioned in insns between loop_start and loop_end
  20510. +   and that are also mentioned outside of the loop
  20511. + */
  20512. + static void
  20513. + mark_regs_live_outside (loop_start, loop_end)
  20514. +      rtx loop_start;
  20515. +      rtx loop_end;
  20516. + {
  20517. +   rtx insn;
  20518. +   int in_loop = 0;
  20519. +   insn = get_insns ();
  20520. +   while (insn)
  20521. +     {
  20522. +       if (insn == loop_start)
  20523. +     {
  20524. +       in_loop = 1;
  20525. +     }
  20526. +       else if (insn == loop_end)
  20527. +     {
  20528. +       in_loop = 0;
  20529. +     }
  20530. +       else if (in_loop == 0 
  20531. +            && (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN 
  20532. +         || GET_CODE (insn) == JUMP_INSN))
  20533. +     {
  20534. +       mark_regs_mentioned (PATTERN (insn), insn);
  20535. +     }
  20536. +       insn = NEXT_INSN (insn);
  20537. +     }
  20538. + }
  20539. + /*
  20540. +   Each register mentioned in pat, except for the destination register of
  20541. +   the insn, is marked as reg_live_outside_loop
  20542. + */
  20543. + static void
  20544. + mark_regs_mentioned (pat, insn)
  20545. +      rtx pat, insn;
  20546. + {
  20547. +   register char *fmt;
  20548. +   register int i;
  20549. +   register enum rtx_code code;
  20550. +   if (GET_CODE (pat) == SET
  20551. +       && GET_CODE (SET_DEST (pat)) == REG && is_a_param_slot (SET_SRC (pat)))
  20552. +     {
  20553. +       return;
  20554. +     }
  20555. +     
  20556. +   code = GET_CODE (pat);
  20557. +   switch (code)
  20558. +     {
  20559. +     case REG:
  20560. +       if (REGNO (pat) < max_reg_before_loop)
  20561. +     {
  20562. +       reg_live_outside_loop[REGNO (pat)] = 1;
  20563. +     }
  20564. +       return;
  20565. +       /* These codes have no constituent expressions
  20566. +      and are unique.  */
  20567. +     case SCRATCH:
  20568. +     case CC0:
  20569. +     case PC:
  20570. +     case QUEUED:
  20571. +     case CONST_INT:
  20572. +     case CONST_DOUBLE:
  20573. +     case SYMBOL_REF:
  20574. +     case CODE_LABEL:
  20575. +       return;
  20576. +     }
  20577. +   fmt = GET_RTX_FORMAT (code);
  20578. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  20579. +     {
  20580. +       if (fmt[i] == 'E')
  20581. +     {
  20582. +       register int j;
  20583. +       for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
  20584. +         mark_regs_mentioned (XVECEXP (pat, i, j), insn);
  20585. +     }
  20586. +       else if (fmt[i] == 'e')
  20587. +     mark_regs_mentioned (XEXP (pat, i), insn);
  20588. +     }
  20589. + }
  20590. + /* Return 1 iff there is a loop_begin note between loop_start and loop_end
  20591. +    otherwise return 0 */
  20592. + static int
  20593. + loop_contains_loop (loop_start, loop_end)
  20594. +      rtx loop_start;
  20595. +      rtx loop_end;
  20596. + {
  20597. +   rtx insn;
  20598. +   insn = NEXT_INSN (loop_start);
  20599. +   while (insn && insn != loop_end)
  20600. +     {
  20601. +       if (GET_CODE (insn) == NOTE
  20602. +       && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
  20603. +     {
  20604. +       return (1);
  20605. +     }
  20606. +       insn = NEXT_INSN (insn);
  20607. +     }
  20608. +   return (0);
  20609. + }
  20610. + /* reload_slots[indx] is a reload slot that was never updated in loop
  20611. +    but could not be lifted only because the register it is
  20612. +    loaded into was also set to something else in loop.
  20613. +    Lets see if the reload slot was set in the basic block
  20614. +    just prior to the loop by some inexpensive operation.
  20615. +    (particularly a move from memory into a register and
  20616. +    a move of that register onto stack). If so lets
  20617. +    replace each load of the reload slot in the loop with
  20618. +    a load of the memory and delete the code that loaded
  20619. +    and spilled it outside the loop.
  20620. +    This corrects the preloading of loop invariants that
  20621. +    could not be held in registers over the loop
  20622. +  */
  20623. + static
  20624. + void 
  20625. + push_load_into_loop (loop_start, loop_end, indx)
  20626. +      rtx loop_start;
  20627. +      rtx loop_end;
  20628. +      int indx;
  20629. + {
  20630. +   rtx insn, insn_sets_reload_slot, val_in_reload_slot, insns_deleted[2],
  20631. +     update_log_links_start, rn, prev, link;
  20632. +   int rindx, i, found_set, num_deleted;
  20633. +   if (loop_dump_stream)
  20634. +     {
  20635. +       fprintf (loop_dump_stream, "\nTry to push load of pseudo %d into loop\n",
  20636. +            reload_slots[indx].stack_slot_pseudo_reg);
  20637. +     }
  20638. +   /* Look for insn before the loop that sets this reload slot */
  20639. +   insn = PREV_INSN (loop_start);
  20640. +   insn_sets_reload_slot = 0;
  20641. +   while (insn && !insn_sets_reload_slot)
  20642. +     {
  20643. +       if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN 
  20644. +       || GET_CODE (insn) == CODE_LABEL 
  20645. +       || (GET_CODE (insn) == NOTE
  20646. +            && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG 
  20647. +                || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
  20648. +               )
  20649. +          ) 
  20650. +       || (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) != SET))
  20651. +     {
  20652. +       break;
  20653. +     }
  20654. +       else if (GET_CODE (insn) == INSN 
  20655. +            && rtx_equal_p (SET_DEST (PATTERN (insn)), reload_slots[indx].reload_stack_slot))
  20656. +     {
  20657. +       insn_sets_reload_slot = insn;
  20658. +     }
  20659. +       insn = PREV_INSN (insn);
  20660. +     }
  20661. +   if (!insn_sets_reload_slot)
  20662. +     {
  20663. +       return;
  20664. +     }
  20665. +   /* Now see if the source is a register and that register is
  20666. +      set by the immediately preceeding insn - then source of
  20667. +      the immediately preceeding insn is the value in the reload
  20668. +      slot throughout the loop */
  20669. +   if (GET_CODE (SET_SRC (PATTERN (insn_sets_reload_slot))) == REG 
  20670. +       && GET_CODE (PREV_INSN (insn_sets_reload_slot)) == INSN 
  20671. +       && GET_CODE (PATTERN (PREV_INSN (insn_sets_reload_slot))) == SET 
  20672. +       && rtx_equal_p (SET_DEST (PATTERN (PREV_INSN (insn_sets_reload_slot))),
  20673. +            SET_SRC (PATTERN (insn_sets_reload_slot))))
  20674. +     {
  20675. +       val_in_reload_slot = SET_SRC (PATTERN (PREV_INSN (insn_sets_reload_slot)));
  20676. +     }
  20677. +   else
  20678. +     {
  20679. +       return;
  20680. +     }
  20681. +   if (is_a_reload_stack_slot (val_in_reload_slot, &rindx, cur_stack_offset, 0))
  20682. +     { /* Don't want to handle these */
  20683. +       return;
  20684. +     }
  20685. +   /* Now make sure that this value is not changed in loop */
  20686. +   if (GET_CODE (val_in_reload_slot) != MEM || !invariant_p (val_in_reload_slot))
  20687. +     {
  20688. +       return;
  20689. +     }
  20690. +   for (i = loop_store_mems_idx - 1; i >= 0; i--)
  20691. +     {
  20692. +       if (true_dependence (loop_store_mems[i], val_in_reload_slot) 
  20693. +       && !is_a_reload_stack_slot (loop_store_mems[i], &rindx, cur_stack_offset, 0)
  20694. +     )
  20695. +     {
  20696. +       return;
  20697. +     }
  20698. +     }
  20699. +   /* Now we know that the value can be substituted and that the store into
  20700. +      the reload slot outside the loop (i.e. insn_sets_reload_slot)
  20701. +      can be deleted.
  20702. +      we also want to delete the load of the reload slot
  20703. +      (i.e PREV_INSN(insn_sets_reload_slot)). we can do this if the register
  20704. +      loaded (i.e. SET_DEST(PATTERN(PREV_INSN(insn_sets_reload_slot))) is
  20705. +      set before used after PREV_INSN(insn_sets_reload_slot))
  20706. +   */
  20707. +   insn = NEXT_INSN (insn_sets_reload_slot);
  20708. +   found_set = 0;
  20709. +   while (!found_set && insn && insn != loop_end)
  20710. +     {
  20711. +       if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN 
  20712. +       || (GET_CODE (insn) == CODE_LABEL && PREV_INSN (insn) != loop_start))
  20713. +     {
  20714. +       break;
  20715. +     }
  20716. +       if (GET_CODE (insn) == INSN)
  20717. +     {
  20718. +       if (reg_overlap_mentioned_p (
  20719. +              SET_DEST (PATTERN (PREV_INSN (insn_sets_reload_slot))),
  20720. +                     PATTERN (insn)))
  20721. +         {
  20722. +           break;
  20723. +         }
  20724. +       if (GET_CODE (PATTERN (insn)) == SET 
  20725. +           && rtx_equal_p (SET_DEST (PATTERN (insn)),
  20726. +             SET_DEST (PATTERN (PREV_INSN (insn_sets_reload_slot)))))
  20727. +         {
  20728. +           found_set = 1;
  20729. +         }
  20730. +     }
  20731. +       insn = NEXT_INSN (insn);
  20732. +     }
  20733. +   /* Do the replacement throughout the loop */
  20734. +   if (loop_dump_stream)
  20735. +     {
  20736. +       fprintf (loop_dump_stream, "replacing reload slot %d with: throughout loop\n",
  20737. +            indx);
  20738. +       tdebug_rtx (val_in_reload_slot, loop_dump_stream);
  20739. +     }
  20740. +   insn = NEXT_INSN (insn_sets_reload_slot);
  20741. +   while (insn != loop_end)
  20742. +     {
  20743. +       if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN 
  20744. +       || GET_CODE (insn) == JUMP_INSN)
  20745. +     {
  20746. +           init_undo_buf ();
  20747. +       subst_in_insn (insn, PATTERN (insn),
  20748. +              reload_slots[indx].reload_stack_slot,
  20749. +              val_in_reload_slot, 1, 0);
  20750. +     }
  20751. +       insn = NEXT_INSN (insn);
  20752. +     }
  20753. +   insns_deleted[0] = NULL;
  20754. +   insns_deleted[1] = NULL;
  20755. +   num_deleted = 0;
  20756. +   update_log_links_start = PREV_INSN (insn_sets_reload_slot);
  20757. +   if (found_set)
  20758. +     {
  20759. +       if (loop_dump_stream)
  20760. +     {
  20761. +       fprintf (loop_dump_stream, " delete insn %d\n",
  20762. +            INSN_UID (PREV_INSN (insn_sets_reload_slot)));
  20763. +     }
  20764. +       insns_deleted[num_deleted++] = PREV_INSN (insn_sets_reload_slot);
  20765. +       delete_insn (PREV_INSN (insn_sets_reload_slot));
  20766. +     }
  20767. +   if (loop_dump_stream)
  20768. +     {
  20769. +       fprintf (loop_dump_stream, " delete insn %d\n",
  20770. +            INSN_UID (insn_sets_reload_slot));
  20771. +     }
  20772. +   insns_deleted[num_deleted++] = insn_sets_reload_slot;
  20773. +   delete_insn (insn_sets_reload_slot);
  20774. +   /* Remove these deleted insns from any log links they are on */
  20775. +   for (rn = update_log_links_start; rn != loop_start; rn = NEXT_INSN (rn))
  20776. +     {
  20777. +       if ((GET_CODE (rn) == INSN || GET_CODE (rn) == JUMP_INSN
  20778. +        || GET_CODE (rn) == CALL_INSN) && LOG_LINKS (rn))
  20779. +     {
  20780. +       for (prev = 0, link = LOG_LINKS (rn); link;
  20781. +            prev = link, link = XEXP (link, 1))
  20782. +         {
  20783. +           if (XEXP (link, 0) == insns_deleted[0] 
  20784. +           || (num_deleted == 2 && XEXP (link, 0) == insns_deleted[1]))
  20785. +         {
  20786. +           if (prev)
  20787. +             XEXP (prev, 1) = XEXP (link, 1);
  20788. +           else
  20789. +             LOG_LINKS (rn) = XEXP (link, 1);
  20790. +         }
  20791. +         }
  20792. +     }
  20793. +     }
  20794. + }
  20795. + void
  20796. + init_undo_buf ()
  20797. + {
  20798. +   undobuf.storage = (char *) oballoc (0);
  20799. +   undobuf.num_undo = 0;
  20800. + }
  20801. + /* In pat of insn replace org with new. If not_dest is 1 then
  20802. +    don't do the rplacement if org is ae destination of a SET
  20803. + */
  20804. + void 
  20805. + subst_in_insn (insn, pat, org, new, not_dest, is_dest)
  20806. +      rtx insn, pat, org, new;
  20807. +      int not_dest;
  20808. +      int is_dest;
  20809. + {
  20810. +   inner_subst_in_insn (insn, pat, &pat, org, new, not_dest, is_dest);
  20811. + }
  20812. + /* In pat of insn replace org with new. If not_dest is 1 then
  20813. +    don't do the rplacement if org is ae destination of a SET
  20814. + */
  20815. + static void 
  20816. + inner_subst_in_insn (insn, pat, where, org, new, not_dest, is_dest)
  20817. +      rtx insn, pat, org, new, *where;
  20818. +      int not_dest;
  20819. +      int is_dest;
  20820. + {
  20821. +   register RTX_CODE code = GET_CODE (pat);
  20822. +   register int i, j;
  20823. +   register char *fmt;
  20824. +   if (not_dest && is_dest)
  20825. +     {
  20826. +       return;
  20827. +     }
  20828. +   switch (code)
  20829. +     {
  20830. +     case HIGH:
  20831. +     case CONST_INT:
  20832. +     case CONST:
  20833. +     case CONST_DOUBLE:
  20834. +     case SYMBOL_REF:
  20835. +     case LABEL_REF:
  20836. +     case PC:
  20837. +     case CC0:
  20838. +       return ;
  20839. +     }
  20840. +   if (rtx_equal_p (pat, org))
  20841. +     {
  20842. +       LOOP_SUBST (where, new);
  20843. +       return;
  20844. +     }
  20845. +   fmt = GET_RTX_FORMAT (code);
  20846. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  20847. +     if (fmt[i] == 'e')
  20848. +       {
  20849. +         if (not_dest && code == SET && i == 0)
  20850. +           is_dest = 1;
  20851. +         else
  20852. +           is_dest = 0;
  20853. +         if( XEXP (pat, i))
  20854. +           inner_subst_in_insn (insn, XEXP (pat, i), &XEXP (pat, i), org, new, not_dest, is_dest);
  20855. +       }
  20856. +     else if (fmt[i] == 'E' || fmt[i] == 'V')
  20857. +       {
  20858. +     for (j = 0; j < XVECLEN (pat, i); j++)
  20859. +       inner_subst_in_insn (insn, XVECEXP (pat, i, j), &XVECEXP (pat, i, j), org, new, not_dest, 0);
  20860. +       }
  20861. + }
  20862. + /* tsl - begin */
  20863. + /* Indexed by i, each entry indicates the last memory, register i was loaded
  20864. +    with, in the current loop (NULL if no reload until now) */
  20865. +    
  20866. + static rtx last_reloads[FIRST_PSEUDO_REGISTER];
  20867. + #define LAST_RELOAD(REGNO) last_reloads[(REGNO)]
  20868. + /* If entry > 0 then the higher it is the less recently used it is.  
  20869. +    If entry == 0 then that register number has not been used as reload
  20870. +    since last lable.  
  20871. +  */
  20872. + static int reload_priority[FIRST_PSEUDO_REGISTER];
  20873. + /* Set of registers that are free and ready to be used at this moment.  */
  20874. + extern HARD_REG_SET free_regs;
  20875. + extern void update_free_regs (rtx);
  20876. + extern int find_free_reg (enum machine_mode);
  20877. + static int find_last_reload (rtx);
  20878. + /* Replaces the reload registers of reload insns as follows:
  20879. +    for each insn which loads memory into a register,
  20880. +    if the reload register is loaded with a memory, which was previously
  20881. +    loaded, and the reload register dies in the next insn, we
  20882. +    replace the reload register, with that already loaded with the stack slot
  20883. +    (assuming that register is free - we use the same free register scanning
  20884. +    method of the memory_simplify() function). 
  20885. +    If the reload register was already used since the last label or call then
  20886. +    try to find a free register which was used less recently and replace the
  20887. +    reload register with the register found.  
  20888. +    */
  20889. + void
  20890. + replace_reload_registers (f, file)
  20891. +      rtx f;
  20892. +      FILE *file;
  20893. + {
  20894. +   HARD_REG_SET saved_free_regs; /* for testing find_free_regs_between () */
  20895. +   /* indicate wheter we are in a loop now */
  20896. +   int in_loop_f = 0;
  20897. +   int save_code;
  20898. +   int i;
  20899. +   /* make flow_analysis without changing the insns and saving the pseudo
  20900. +      registers information in basic_block_live_at_start */
  20901. +   hard_reg_flow_analysis (f, file, 1 /* save pseudo register information */);
  20902. +   have_flow_analysis = 1;
  20903. +   bzero (last_reloads, sizeof last_reloads);
  20904. +   if (n_basic_blocks > 0)
  20905. +     {
  20906. +       register int regno, block;
  20907. +       /* To determine which registers are live after any insn, start from
  20908. +      the beginning of the basic block and scan insns, noting
  20909. +          which registers are set by each insn and which die there. */
  20910. +       for (block = 0; block < n_basic_blocks; block++)
  20911. +     {
  20912. +       register rtx insn;
  20913. +       int end_of_block_f;
  20914. +       if (file)
  20915. +         fprintf (file, "\nblock number: %d:\n", block);
  20916. +       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  20917. +         /* at the beginning of a block, each non-live hard register is
  20918. +            considered free. */
  20919. +         {
  20920. +           register int offset = regno / REGSET_ELT_BITS;
  20921. +           register int bit = 1 << (regno % REGSET_ELT_BITS);
  20922. +           if (basic_block_live_at_start[block][offset] & bit)
  20923. +         CLEAR_HARD_REG_BIT (free_regs, regno);
  20924. +           else
  20925. +         SET_HARD_REG_BIT (free_regs, regno);
  20926. +         }
  20927. +       end_of_block_f = 0;    /* signals the end of block reached */
  20928. +       /* Traverse the block, an insn by insn.  Maintain a history
  20929. +          of free registers and registers used to load memory
  20930. +          for use only in next insn (these are called reload_registers).  
  20931. +          At CALLs and CODE_LABELs restart the history of reload_registers.
  20932. +       */
  20933. +       for (insn = basic_block_head[block];
  20934. +            ! end_of_block_f;
  20935. +            insn = NEXT_INSN (insn))
  20936. +         {
  20937. +           rtx note, next, pat;
  20938. +           rtx loop_start; /* use to test find_free_regs_between () */
  20939. +           int regno;
  20940. +           if (GET_CODE (insn) == CALL_INSN)
  20941. +         {
  20942. +               bzero (last_reloads, sizeof last_reloads);
  20943. +               bzero (reload_priority, sizeof reload_priority);
  20944. +             }
  20945. +           if (GET_CODE (insn) == CODE_LABEL)
  20946. +         {
  20947. +               bzero (last_reloads, sizeof last_reloads);
  20948. +               bzero (reload_priority, sizeof reload_priority);
  20949. +               loop_start = insn;
  20950. +               if (GET_CODE (PREV_INSN (insn)) == NOTE
  20951. +                   && NOTE_LINE_NUMBER (PREV_INSN (insn)) 
  20952. +                     == NOTE_INSN_LOOP_BEG)
  20953. +                 {
  20954. +                   in_loop_f = 1;
  20955. +                   saved_free_regs = free_regs;
  20956. +                 }
  20957. +             }
  20958. +           if (GET_CODE (insn) == JUMP_INSN
  20959. +           && GET_CODE (NEXT_INSN (insn)) == NOTE
  20960. +           && NOTE_LINE_NUMBER (NEXT_INSN (insn)) == NOTE_INSN_LOOP_END)
  20961. +         {
  20962. +           register int regno;
  20963. + #if 0
  20964. +               if (in_loop_f)
  20965. +             {
  20966. +               find_free_regs_between (& saved_free_regs,
  20967. +                             loop_start,
  20968. +                             insn);
  20969. +               if (file)
  20970. +                 {
  20971. +                   fprintf (file,
  20972. +                              "free regs found in loop (insns %d - %d): ",
  20973. +                              INSN_UID (loop_start), INSN_UID (insn));
  20974. +                   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  20975. +                     if (TEST_HARD_REG_BIT (saved_free_regs, regno))
  20976. +                       fprintf (file, "%d ", regno);
  20977. +                   fprintf (file, "\n");
  20978. +                 }
  20979. +             }
  20980. + #endif
  20981. +           in_loop_f = 0;
  20982. +         }
  20983. +         
  20984. +           if (/*in_loop_f*/ 1)
  20985. +             {
  20986. +           if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
  20987. +               /*&& RTX_IS_SPILL_P (insn)*/
  20988. +               && (pat = PATTERN (insn))
  20989. +                   && GET_CODE (pat) == SET
  20990. +                   && GET_CODE (SET_DEST (pat)) == REG
  20991. +                   && GET_CODE (SET_SRC (pat)) == MEM)
  20992. +                 {
  20993. +                   regno = REGNO (SET_DEST (pat));
  20994. +                   if ((next = next_nonnote_insn (insn))
  20995. +                       && GET_CODE (next) == INSN
  20996. +                       && (note = find_regno_note (next,
  20997. +                               REG_DEAD,
  20998. +                               regno)))
  20999. +             {
  21000. +               /* look for new_regno to replace with */
  21001. +                   int new_regno = find_last_reload (SET_SRC (pat));
  21002. +                   enum machine_mode mode = GET_MODE (SET_DEST (pat));
  21003. +                           /* tevid */
  21004. +                           if (new_regno != FIRST_PSEUDO_REGISTER)
  21005. +                             { /* The mode must be ok */
  21006. +                               if (!HARD_REGNO_MODE_OK (new_regno, mode))
  21007. +                                 new_regno = FIRST_PSEUDO_REGISTER;
  21008. +                             }
  21009. +                   if (new_regno == FIRST_PSEUDO_REGISTER
  21010. +                   || ! TEST_HARD_REG_BIT (free_regs, new_regno))
  21011. +                 if (/*LAST_RELOAD (regno)*/
  21012. +                     reload_priority[regno])
  21013. +                   /* if we already used regno for reload in this
  21014. +                      loop it is better to reload the new memory
  21015. +                      to another register (if we find free one) */
  21016. +                   {
  21017. +                     new_regno = find_free_reg (mode);
  21018. +                     if (reload_priority [new_regno] &&
  21019. +                         reload_priority [regno] >=
  21020. +                         reload_priority [new_regno])
  21021. +                       {
  21022. +                         new_regno = FIRST_PSEUDO_REGISTER;
  21023. +                       }
  21024. +                   }
  21025. +                 else
  21026. +                   /* this is the first time we're using this
  21027. +                      register for reload in the current loop -
  21028. +                      so we need no replacement */
  21029. +                   new_regno = FIRST_PSEUDO_REGISTER;
  21030. +               if (new_regno != FIRST_PSEUDO_REGISTER
  21031. +                   /* if regno == new_regno no replcement needed */
  21032. +                   && new_regno != regno)
  21033. +                         {
  21034. +                           register int nregs, i;
  21035. +                           int stop_replacement = 0;
  21036. +                       rtx new_reg = gen_rtx (REG, mode, new_regno);
  21037. +                           rtx old_reg = XEXP (note, 0);
  21038. +                       /* replace this register in the next insn */
  21039. +                               init_undo_buf ();
  21040. +                       subst_in_insn (next,
  21041. +                                  PATTERN (next),
  21042. +                                  old_reg,
  21043. +                                  new_reg,
  21044. +                                  0,
  21045. +                                  0);
  21046. + #ifdef REGISTER_CONSTRAINTS
  21047. +                               save_code = INSN_CODE (next);
  21048. +                           if ((INSN_CODE (next) = recog (PATTERN (next),
  21049. +                                  next,
  21050. +                                  0)) != -1)
  21051. +                         insn_extract (next);
  21052. +                       if (INSN_CODE (next) == -1
  21053. +                           || !constrain_operands (INSN_CODE (next), 1))
  21054. +                         {
  21055. +                       /* restore the previous situation */
  21056. +                       INSN_CODE (next) = save_code;
  21057. +                       loop_undo_all ();
  21058. +                           /*subst_in_insn (next,
  21059. +                                      PATTERN (next),
  21060. +                                      new_reg,
  21061. +                                      old_reg,
  21062. +                                      0,
  21063. +                                      0);*/
  21064. +                           stop_replacement = 1;
  21065. +                          }
  21066. + #endif
  21067. +                        if (! stop_replacement)
  21068. +                          {
  21069. +                            rtx next_dest = SET_DEST (PATTERN (next));
  21070. +                               /* replace this insn's register with regno */
  21071. +                               SET_DEST (pat) = new_reg;
  21072. + #if 0
  21073. +                                   init_undo_buf ();
  21074. +                           subst_in_insn (next,
  21075. +                          note,
  21076. +                          old_reg,
  21077. +                          new_reg,
  21078. +                          0,
  21079. +                          0);
  21080. + #endif
  21081. +                   /* The regno in the REG_DEAD note should be
  21082. +                      changed */
  21083. +                   XEXP (note, 0) = new_reg;
  21084. +                   
  21085. +                   /* Now, if we replaced a REG_DEAD note, and
  21086. +                      the new_reg is the destination of the next
  21087. +                      insn, we should remove this note */
  21088. +                   /* tevid replaced regno with new_regno,
  21089. +                      twice */
  21090. +                   if (GET_CODE (next_dest) == REG
  21091. +                       && REGNO (next_dest) == new_regno)
  21092. +                     remove_death (new_regno, next);
  21093. +               
  21094. +                   /* replace the registers in the free_register
  21095. +                      list */
  21096. +                   nregs = HARD_REGNO_NREGS (new_regno, mode);
  21097. +                   for (i = 0; i < nregs; i++)
  21098. +                     CLEAR_HARD_REG_BIT (free_regs, new_regno + i);
  21099. +                   nregs = HARD_REGNO_NREGS (regno, mode);
  21100. +                   for (i = 0; i < nregs; i++)
  21101. +                     SET_HARD_REG_BIT (free_regs, regno + i);
  21102. +                   if (file)
  21103. +                     {
  21104. +                       fprintf (file, "insn %d: reload register",
  21105. +                                    INSN_UID (insn));
  21106. +                       fprintf (file, " replaced (old %d new %d)\n",
  21107. +                       regno, new_regno);
  21108. +                     }
  21109. + #ifdef REGISTER_CONSTRAINTS
  21110. +                 }  /* if (! stop_replacement) */
  21111. + #endif
  21112. +                 }  /* if (new_regno != FIRST_PSEUDO_REGISTER
  21113. +                           && new_regno != regno) */
  21114. +                 else if (file)
  21115. +                    {
  21116. +                      fprintf (file, "insn %d: no free register for",
  21117. +                                    INSN_UID (insn));
  21118. +                  fprintf (file, " reload replacement\n");
  21119. +                    }
  21120. +             }  /* if (next = next_nonnote (insn))
  21121. +                   && (note = find_regno_note (next,
  21122. +                                     REG_DEAD,
  21123. +                                     regno))) */
  21124. +               for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  21125. +                 if (reload_priority[i] > 0)
  21126. +                   reload_priority[i]++;
  21127. +               reload_priority[REGNO (SET_DEST (PATTERN (insn)))] = 1;
  21128. +                 }  /* if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
  21129. +                       && RTX_IS_SPILL_P (insn)
  21130. +                       && (pat = PATTERN (insn))
  21131. +                           && GET_CODE (pat) == SET
  21132. +                           && GET_CODE (SET_DEST (pat)) == REG */
  21133. +           /* update the last_reloads array */
  21134. +           if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
  21135. +               && (pat = PATTERN (insn))
  21136. +                   && GET_CODE (pat) == SET
  21137. +                   && GET_CODE (SET_DEST (pat)) == REG
  21138. +                   && GET_CODE (SET_SRC (pat)) == MEM)
  21139. +                 LAST_RELOAD (REGNO (SET_DEST (pat ))) = SET_SRC (pat);
  21140. +             }  /* if (in_loop_f) */
  21141. +           end_of_block_f = (insn == basic_block_end[block]);
  21142. +           if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
  21143. +             {
  21144. +               register int j;
  21145. +               rtx set;
  21146. +               if (GET_CODE (insn) == CALL_INSN)
  21147. +             /* all call clobbered registers are now free */
  21148. +             for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
  21149. +               if (call_used_regs[j])
  21150. +                 SET_HARD_REG_BIT (free_regs, j);
  21151. +           update_free_regs (PATTERN (insn));
  21152. +           /* Update LAST_RELOADs that are no longer valid */
  21153. +           update_last_reloads ( PATTERN (insn));
  21154. +              
  21155. +           /* add each dead register to the free_regs set */
  21156. +           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
  21157. +             if ((REG_NOTE_KIND (note) == REG_DEAD
  21158. +                  || REG_NOTE_KIND (note) == REG_UNUSED)
  21159. +                 && GET_CODE (XEXP (note, 0)) == REG)
  21160. +               {
  21161. +             register int i;
  21162. +                 register int regno = REGNO (XEXP (note, 0));
  21163. +                 register int nregs = 
  21164. +                 HARD_REGNO_NREGS (regno, GET_MODE (XEXP (note, 0)));
  21165. +                 for (i = 0; i < nregs; i++)
  21166. +               SET_HARD_REG_BIT (free_regs, regno + i);
  21167. +               }
  21168. +           if ((note = find_reg_note (insn, REG_WAS_0, 0)))
  21169. +             {
  21170. +               set = single_set (insn);
  21171. +               if (set == NULL 
  21172. +                   || GET_CODE (SET_DEST (set)) == REG)
  21173. +                 { /* Since reg may have been reused.  */
  21174. +                   remove_note (insn, note);
  21175. +                 }
  21176. +             }
  21177. +         }
  21178. +         }  /* for (insn = basic_block_head[block]; */
  21179. +     }  /* for (block = 0; block < n_basic_blocks; block++) */
  21180. +     }  /* if (n_basic_blocks > 0) */
  21181. + }  /* replace_reload_registers (file, f) */
  21182. + /* Returns a hard register regno, if the contents of entry regno in
  21183. +    last_reloads array equals to MEM, FIRST_PSEUDO_REGISTER otherwise. */
  21184. + static int
  21185. + find_last_reload (rtx mem)
  21186. + {
  21187. +   register int regno;
  21188. +   
  21189. +   if (GET_CODE (mem) != MEM)
  21190. +     abort ();
  21191. +   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  21192. +     /* tevid added test of LAST_RELOAD (regno) != NULL and XEXPs */
  21193. +     if (LAST_RELOAD (regno) != NULL
  21194. +         && rtx_equal_p (XEXP (LAST_RELOAD (regno), 0), XEXP (mem, 0)))
  21195. +       return (regno);
  21196. +   return (FIRST_PSEUDO_REGISTER);
  21197. + }
  21198. + /* Keep track of effect of pat on last_reloads[]. Note that making
  21199. +    an error will not effect the correctness of the code.  */
  21200. +    
  21201. + static void
  21202. + update_last_reloads (rtx pat)
  21203. + {
  21204. +   register int i, j, regno, nregs;
  21205. +   rtx set_src, set_dest;
  21206. +   register char *fmt;
  21207. +   register RTX_CODE code = GET_CODE (pat);
  21208. +   switch (GET_CODE (pat))
  21209. +     {
  21210. +       case SET:
  21211. +       case CLOBBER:
  21212. +         set_dest = SET_DEST (pat);
  21213. +         if (GET_CODE (set_dest) == REG)
  21214. +           {
  21215. +             regno = REGNO (set_dest);
  21216. +             nregs = HARD_REGNO_NREGS (regno, GET_MODE (set_dest));
  21217. +             if (nregs != 1)
  21218. +               {
  21219. +             bzero (last_reloads, sizeof last_reloads);
  21220. +               }
  21221. +             else
  21222. +               {
  21223. +                 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  21224. +                   {
  21225. +                     if (LAST_RELOAD (i))
  21226. +                       {
  21227. +                         if (reg_overlap_mentioned_p (set_dest, LAST_RELOAD (i)))
  21228. +                           {
  21229. +                             LAST_RELOAD (i) = NULL;
  21230. +                           }
  21231. +                       }
  21232. +                   }
  21233. +               }
  21234. +           }
  21235. +         else if (GET_CODE (set_dest) == SUBREG)
  21236. +           {
  21237. +             if (GET_CODE (SUBREG_REG (set_dest)) == REG)
  21238. +               {
  21239. +                 regno = REGNO (SUBREG_REG (set_dest)) + SUBREG_WORD (set_dest);
  21240. +                 nregs 
  21241. +                   = HARD_REGNO_NREGS (regno, GET_MODE (SUBREG_REG (set_dest)));
  21242. +                 if (nregs != 1)
  21243. +                   {
  21244. +                 bzero (last_reloads, sizeof last_reloads);
  21245. +                   }
  21246. +                 else
  21247. +                   {
  21248. +                     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  21249. +                       {
  21250. +                         if (LAST_RELOAD (i))
  21251. +                           {
  21252. +                             if (reg_overlap_mentioned_p (SUBREG_REG (set_dest), 
  21253. +                             LAST_RELOAD (i)))
  21254. +                               {
  21255. +                                 LAST_RELOAD (i) = NULL;
  21256. +                               }
  21257. +                           }
  21258. +                       }
  21259. +                   }
  21260. +               }
  21261. +             return;
  21262. +           }
  21263. +         else if (GET_CODE (set_dest) == MEM)
  21264. +           {
  21265. +         for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  21266. +           if (LAST_RELOAD (i)
  21267. +               && true_dependence (set_dest, LAST_RELOAD (i)))
  21268. +             LAST_RELOAD (i) = 0;
  21269. +         update_last_reloads (XEXP (set_dest, 0));
  21270. +             return;
  21271. +           }
  21272. +       case CALL:
  21273. +     for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
  21274. +       if (call_used_regs[j])
  21275. +         LAST_RELOAD (j) = NULL;
  21276. +         return;
  21277. +       case PRE_DEC:
  21278. +       case PRE_INC:
  21279. +       case POST_DEC:
  21280. +       case POST_INC:
  21281. +         if (GET_CODE (XEXP (pat ,0)) == REG)
  21282. +           {
  21283. +             regno = REGNO (XEXP (pat ,0));
  21284. +             nregs = HARD_REGNO_NREGS (regno, GET_MODE (XEXP (pat ,0)));
  21285. +             if (nregs != 1)
  21286. +               {
  21287. +             bzero (last_reloads, sizeof last_reloads);
  21288. +               }
  21289. +             else
  21290. +               {
  21291. +                 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  21292. +                   {
  21293. +                     if (LAST_RELOAD (i))
  21294. +                       {
  21295. +                         if (reg_overlap_mentioned_p (XEXP (pat ,0), LAST_RELOAD (i)))
  21296. +                           {
  21297. +                             LAST_RELOAD (i) = NULL;
  21298. +                           }
  21299. +                       }
  21300. +                   }
  21301. +               }
  21302. +           }
  21303. +         return;
  21304. +     case HIGH:
  21305. +     case CONST_INT:
  21306. +     case CONST:
  21307. +     case CONST_DOUBLE:
  21308. +     case SYMBOL_REF:
  21309. +     case LABEL_REF:
  21310. +     case PC:
  21311. +     case CC0:
  21312. +     case REG:
  21313. +     /*case SUBREG:*/
  21314. +         /* do nothing */
  21315. +         return;
  21316. +   }  /* switch (GET_CODE (pat)) */
  21317. +   fmt = GET_RTX_FORMAT (code);
  21318. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  21319. +     if (fmt[i] == 'e')
  21320. +       {
  21321. +         if( XEXP (pat, i))
  21322. +           update_last_reloads (XEXP (pat, i));
  21323. +       }
  21324. +     else if (fmt[i] == 'E' || fmt[i] == 'V')
  21325. +       {
  21326. +     for (j = 0; j < XVECLEN (pat, i); j++)
  21327. +       update_last_reloads (XVECEXP (pat, i, j));
  21328. +       }
  21329. + }  
  21330. + /* tsl - end */
  21331. + static unsigned int largest_himode_const;
  21332. + #define MAX_COMP_REGS 4
  21333. + struct sign_extension_info {
  21334. +   rtx insn_set;
  21335. +   int num_comp_regs;
  21336. +   struct comp_to_reg {
  21337. +     int regno;
  21338. +     rtx comp_insn;
  21339. +     rtx *where;
  21340. +     unsigned char for_equality;
  21341. +   } compare_to_reg [MAX_COMP_REGS];
  21342. + };
  21343. + static struct sign_extension_info * sign_extension_infos;
  21344. + static void
  21345. + sign_extension_reduction (loop_start, loop_end)
  21346. +   rtx loop_start, loop_end;
  21347. + {
  21348. +   int cur_max_regnum = max_reg_num ();
  21349. +   int found_sign_extension = 0, regno, i, j;
  21350. +   rtx insn, sign_ext_reg;
  21351. +   sign_extension_infos 
  21352. +     = (struct  sign_extension_info *) 
  21353. +       alloca ( sizeof (struct sign_extension_info) * cur_max_regnum);
  21354. +   bzero (sign_extension_infos, 
  21355. +          sizeof (struct sign_extension_info) * cur_max_regnum);
  21356. +   largest_himode_const = 256;
  21357. +   if (sizeof (unsigned int) <= GET_MODE_SIZE (HImode))
  21358. +     {
  21359. +       return ;
  21360. +     }
  21361. +   for (i = 0; i < GET_MODE_SIZE (HImode); i++)
  21362. +     {
  21363. +       largest_himode_const *= 256;
  21364. +     }
  21365. +   largest_himode_const -= 1;
  21366. +   /* Go over loop - mark registers set by sign extension */
  21367. +   for (insn = loop_start; insn && insn != loop_end; insn = NEXT_INSN (insn))
  21368. +     {
  21369. +       if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
  21370. +           && GET_CODE (SET_DEST (PATTERN (insn))) == REG 
  21371. +           && GET_CODE (SET_SRC (PATTERN (insn))) == SIGN_EXTEND
  21372. +           && GET_MODE (SET_DEST (PATTERN (insn))) == SImode
  21373. +           && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == HImode)
  21374. +          { /* Found one.  */
  21375. +            regno = REGNO (SET_DEST (PATTERN (insn)));
  21376. +            if ( regno >= cur_max_regnum)
  21377. +              {
  21378. +                return;
  21379. +              }
  21380. +            found_sign_extension++;
  21381. +            if (sign_extension_infos[regno].insn_set)
  21382. +              {
  21383. +                return;
  21384. +              }
  21385. +            sign_extension_infos[regno].insn_set = insn;
  21386. +          }
  21387. +     }
  21388. +   if (!found_sign_extension || insn != loop_end)
  21389. +     {
  21390. +       return;
  21391. +     }
  21392. +   /* Find all uses of each register marked above */
  21393. +   for (i = FIRST_PSEUDO_REGISTER; i < cur_max_regnum; i++)
  21394. +     {
  21395. +       if (sign_extension_infos[i].insn_set)
  21396. +         {
  21397. +           for (insn = loop_start; insn != loop_end; insn = NEXT_INSN (insn))
  21398. +             {
  21399. +               if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
  21400. +                   || GET_CODE (insn) == JUMP_INSN)
  21401. +                 {
  21402. +                   
  21403. +                   validate_all_references (i, insn, PATTERN (insn));
  21404. +                 }
  21405. +             }
  21406. +         }
  21407. +     }
  21408. +   for (i = FIRST_PSEUDO_REGISTER; i < cur_max_regnum; i++)
  21409. +     {
  21410. +       if (sign_extension_infos[i].insn_set)
  21411. +         {
  21412. +           sign_ext_reg = SET_DEST (PATTERN (sign_extension_infos[i].insn_set));
  21413. +           if (reg_used_between_p (sign_ext_reg,
  21414. +                                   get_insns (), loop_start) ||
  21415. +               reg_used_between_p (sign_ext_reg,
  21416. +                                   loop_end, NULL)
  21417. +              )
  21418. +             {
  21419. +               sign_extension_infos[i].insn_set = NULL;
  21420. +             }
  21421. +         }
  21422. +     }
  21423. +   /* Check which registers can be sign extension reduced */
  21424. +   for (i = FIRST_PSEUDO_REGISTER; i < cur_max_regnum; i++)
  21425. +     {
  21426. +       if (sign_extension_infos[i].insn_set)
  21427. +         {
  21428. +           j = 0;
  21429. +           while (j < sign_extension_infos[i].num_comp_regs
  21430. +                  && sign_extension_infos[i].insn_set)
  21431. +             {
  21432. +               regno = sign_extension_infos[i].compare_to_reg[j].regno;
  21433. +               if (regno < FIRST_PSEUDO_REGISTER)
  21434. +                 {
  21435. +                   sign_extension_infos[i].insn_set = NULL;
  21436. +                 }
  21437. +               if (sign_extension_infos[regno].insn_set == NULL)
  21438. +                 {
  21439. +                   sign_extension_infos[i].insn_set = NULL;
  21440. +                 }
  21441. +               j++;
  21442. +             }
  21443. +         }
  21444. +     }
  21445. +   /* Do the optimization.  */
  21446. +   for (i = FIRST_PSEUDO_REGISTER; i < cur_max_regnum; i++)
  21447. +     {
  21448. +       if (sign_extension_infos[i].insn_set)
  21449. +         {
  21450. +           rtx subreg, strict_subreg;
  21451. +           subreg 
  21452. +             = gen_rtx (SUBREG, HImode, 
  21453. +               SET_DEST (PATTERN (sign_extension_infos[i].insn_set)),
  21454. +               0);
  21455. +           strict_subreg = gen_rtx (STRICT_LOW_PART, 0, subreg);
  21456. +           emit_insn_before (gen_rtx (SET, 0, 
  21457. +              SET_DEST (PATTERN (sign_extension_infos[i].insn_set)),
  21458. +              const0_rtx), loop_start);
  21459. +           emit_insn_before (gen_rtx (USE, 0, 
  21460. +              SET_DEST (PATTERN (sign_extension_infos[i].insn_set))),
  21461. +              loop_start);
  21462. +           SET_DEST (PATTERN (sign_extension_infos[i].insn_set)) 
  21463. +             = strict_subreg;
  21464. +           SET_SRC (PATTERN (sign_extension_infos[i].insn_set)) 
  21465. +             = XEXP (SET_SRC (PATTERN (sign_extension_infos[i].insn_set)), 0);
  21466. +           INSN_CODE (sign_extension_infos[i].insn_set) = -1;
  21467. +           j = 0;
  21468. +           while (j < sign_extension_infos[i].num_comp_regs)
  21469. +             {
  21470. +               if (sign_extension_infos[i].compare_to_reg[j].for_equality == 0)
  21471. +                 {
  21472. +                   *sign_extension_infos[i].compare_to_reg[j].where
  21473. +                     = subreg;
  21474. +                   INSN_CODE (sign_extension_infos[i].compare_to_reg[j].comp_insn)
  21475. +                     = -1;
  21476. +                 }
  21477. +               j++;
  21478. +             }
  21479. +         }
  21480. +     }
  21481. + }
  21482. + static void
  21483. + validate_all_references (regno, insn, pat)
  21484. +   int regno;
  21485. +   rtx insn, pat;
  21486. + {
  21487. +   register RTX_CODE code = GET_CODE (pat);
  21488. +   register int i, j, val;
  21489. +   register char *fmt;
  21490. +   int num_comp_regs, comp_regno, for_equality = 0;
  21491. +   rtx next;
  21492. +   switch (code)
  21493. +     {
  21494. +     case HIGH:
  21495. +     case CONST_INT:
  21496. +     case CONST:
  21497. +     case CONST_DOUBLE:
  21498. +     case SYMBOL_REF:
  21499. +     case LABEL_REF:
  21500. +     case PC:
  21501. +     case CC0:
  21502. +       return ;
  21503. +     case REG:
  21504. +       if (REGNO (pat) == regno)
  21505. +         {
  21506. +           sign_extension_infos[regno].insn_set = NULL;
  21507. +         }
  21508. +       break;
  21509. +       
  21510. +     case SET:
  21511. +       if (GET_CODE (SET_DEST (pat)) == REG 
  21512. +           && REGNO (SET_DEST (pat)) == regno
  21513. +           && sign_extension_infos[REGNO (SET_DEST (pat))].insn_set != insn)
  21514. +         {
  21515. +           if (GET_CODE (SET_SRC (pat)) != CONST_INT)
  21516. +             {
  21517. +               sign_extension_infos[regno].insn_set = NULL;
  21518. +             }
  21519. +           if (GET_MODE (SET_DEST (pat)) != SImode)
  21520. +             {
  21521. +               sign_extension_infos[regno].insn_set = NULL;
  21522. +             }
  21523. +           val = XINT (SET_SRC (pat), 0);
  21524. +           if (val < 0 || val > largest_himode_const)
  21525. +             {
  21526. +               sign_extension_infos[regno].insn_set = NULL;
  21527. +             }
  21528. +           validate_all_references (regno, insn, SET_SRC (pat));
  21529. +           return;
  21530. +         }
  21531. +       else if (GET_CODE (SET_DEST (pat)) == REG 
  21532. +           && REGNO (SET_DEST (pat)) == regno
  21533. +           && sign_extension_infos[REGNO (SET_DEST (pat))].insn_set == insn)
  21534. +         {
  21535. +           return;
  21536. +         }
  21537. +       break;
  21538. +     case AND:
  21539. +       if (GET_CODE (XEXP (pat, 0)) == REG 
  21540. +           && REGNO (XEXP (pat, 0)) == regno)
  21541. +         {
  21542. +           if (GET_CODE (XEXP (pat, 1)) != CONST_INT)
  21543. +             {
  21544. +               sign_extension_infos[regno].insn_set = NULL;
  21545. +             }
  21546. +           if (GET_MODE (XEXP (pat, 0)) != SImode)
  21547. +             {
  21548. +               sign_extension_infos[regno].insn_set = NULL;
  21549. +             }
  21550. +           val = XINT (XEXP (pat, 1), 0);
  21551. +           if (val < 0 || val > largest_himode_const)
  21552. +             {
  21553. +               sign_extension_infos[regno].insn_set = NULL;
  21554. +             }
  21555. +           validate_all_references (regno, insn, XEXP (pat, 1));
  21556. +           return;
  21557. +         }
  21558. +       else if (GET_CODE (XEXP (pat, 1)) == REG 
  21559. +           && REGNO (XEXP (pat, 1)) == regno)
  21560. +         {
  21561. +           if (GET_CODE (XEXP (pat, 0)) != CONST_INT)
  21562. +             {
  21563. +               sign_extension_infos[regno].insn_set = NULL;
  21564. +             }
  21565. +           if (GET_MODE (XEXP (pat, 1)) != SImode)
  21566. +             {
  21567. +               sign_extension_infos[regno].insn_set = NULL;
  21568. +             }
  21569. +           val = XINT (XEXP (pat, 0), 0);
  21570. +           if (val < 0 || val > largest_himode_const)
  21571. +             {
  21572. +               sign_extension_infos[regno].insn_set = NULL;
  21573. +             }
  21574. +           validate_all_references (regno, insn, XEXP (pat, 0));
  21575. +           return;
  21576. +         }
  21577. +       break;
  21578. +     case COMPARE:
  21579. +       next = NEXT_INSN (insn);
  21580. +       if (GET_CODE (next) == JUMP_INSN 
  21581. +       && GET_CODE (PATTERN (next)) == SET 
  21582. +       && SET_DEST (PATTERN (next)) == pc_rtx 
  21583. +       && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE
  21584. +       && (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == NE
  21585. +           ||
  21586. +           GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == EQ))
  21587. +     {
  21588. +       for_equality = 1;
  21589. +     }
  21590. +       if (GET_CODE (XEXP (pat, 0)) == REG 
  21591. +           && REGNO (XEXP (pat, 0)) == regno)
  21592. +         {
  21593. +           if (GET_MODE (XEXP (pat, 0)) != SImode)
  21594. +             {
  21595. +               sign_extension_infos[regno].insn_set = NULL;
  21596. +             }
  21597. +           if (GET_CODE (XEXP (pat, 1)) == CONST_INT)
  21598. +             {
  21599. +               val = XINT (XEXP (pat, 1), 0);
  21600. +               if (for_equality == 0 || val < 0 || val > largest_himode_const)
  21601. +                 {
  21602. +                   sign_extension_infos[regno].insn_set = NULL;
  21603. +                 }
  21604. +             }
  21605. +           else if (GET_CODE (XEXP (pat, 1)) == REG)
  21606. +             {
  21607. +               if (GET_MODE (XEXP (pat, 1)) != SImode)
  21608. +                 {
  21609. +                   sign_extension_infos[regno].insn_set = NULL;
  21610. +                 }
  21611. + #ifndef HAVE_cmphi
  21612. +               sign_extension_infos[regno].insn_set = NULL;
  21613. + #else
  21614. +               if (!HAVE_cmphi)
  21615. +                 {
  21616. +                   sign_extension_infos[regno].insn_set = NULL;
  21617. +                 }
  21618. + #endif
  21619. +               comp_regno = REGNO (XEXP (pat, 1));
  21620. +               if (!sign_extension_infos[comp_regno].insn_set)
  21621. +                 {
  21622. +                   sign_extension_infos[regno].insn_set = NULL;
  21623. +                 }
  21624. +               else
  21625. +                 {
  21626. +                   num_comp_regs 
  21627. +                     = sign_extension_infos[regno].num_comp_regs;
  21628. +                   if (num_comp_regs >= MAX_COMP_REGS)
  21629. +                     {
  21630. +                       sign_extension_infos[regno].insn_set = NULL;
  21631. +                     }
  21632. +                   sign_extension_infos[regno].
  21633. +                       compare_to_reg[num_comp_regs].where = 
  21634. +                     &XEXP (pat, 0);
  21635. +                   sign_extension_infos[regno].
  21636. +                       compare_to_reg[num_comp_regs].comp_insn = insn;
  21637. +                   sign_extension_infos[regno].
  21638. +                       compare_to_reg[num_comp_regs].regno = 
  21639. +                     comp_regno;
  21640. +               sign_extension_infos[regno].
  21641. +                  compare_to_reg[num_comp_regs].for_equality = for_equality;
  21642. +                   sign_extension_infos[regno].num_comp_regs++;
  21643. +                 }
  21644. +             }
  21645. +           else
  21646. +             {
  21647. +               sign_extension_infos[regno].insn_set = NULL;
  21648. +               validate_all_references (regno, insn, XEXP (pat, 1));
  21649. +             }
  21650. +           return;
  21651. +         }
  21652. +       else if (GET_CODE (XEXP (pat, 1)) == REG 
  21653. +           && REGNO (XEXP (pat, 1)) == regno)
  21654. +         {
  21655. +           if (GET_MODE (XEXP (pat, 1)) != SImode)
  21656. +             {
  21657. +               sign_extension_infos[regno].insn_set = NULL;
  21658. +             }
  21659. +           if (GET_CODE (XEXP (pat, 0)) == CONST_INT)
  21660. +             {
  21661. +               val = XINT (XEXP (pat, 0), 0);
  21662. +               if (for_equality == 0 || val < 0 || val > largest_himode_const)
  21663. +                 {
  21664. +                   sign_extension_infos[regno].insn_set = NULL;
  21665. +                 }
  21666. +             }
  21667. +           else if (GET_CODE (XEXP (pat, 0)) == REG)
  21668. +             {
  21669. +               if (GET_MODE (XEXP (pat, 0)) != SImode)
  21670. +                 {
  21671. +                   sign_extension_infos[regno].insn_set = NULL;
  21672. +                 }
  21673. + #ifndef HAVE_cmphi
  21674. +               sign_extension_infos[regno].insn_set = NULL;
  21675. + #else
  21676. +               if (!HAVE_cmphi)
  21677. +                 {
  21678. +                   sign_extension_infos[regno].insn_set = NULL;
  21679. +                 }
  21680. + #endif
  21681. +               comp_regno = REGNO (XEXP (pat, 0));
  21682. +               if (!sign_extension_infos[comp_regno].insn_set)
  21683. +                 {
  21684. +                   sign_extension_infos[regno].insn_set = NULL;
  21685. +                 }
  21686. +               else
  21687. +                 {
  21688. +                   num_comp_regs 
  21689. +                     = sign_extension_infos[regno].num_comp_regs;
  21690. +                   if (num_comp_regs >= MAX_COMP_REGS)
  21691. +                     {
  21692. +                       sign_extension_infos[regno].insn_set = NULL;
  21693. +                     }
  21694. +                   sign_extension_infos[regno].
  21695. +                       compare_to_reg[num_comp_regs].where = 
  21696. +                     &XEXP (pat, 1);
  21697. +                   sign_extension_infos[regno].
  21698. +                       compare_to_reg[num_comp_regs].comp_insn = insn;
  21699. +                   sign_extension_infos[regno].
  21700. +                       compare_to_reg[num_comp_regs].regno = 
  21701. +                     comp_regno;
  21702. +               sign_extension_infos[regno].
  21703. +                  compare_to_reg[num_comp_regs].for_equality = for_equality;
  21704. +                   sign_extension_infos[regno].num_comp_regs++;
  21705. +                 }
  21706. +             }
  21707. +           else
  21708. +             {
  21709. +               sign_extension_infos[regno].insn_set = NULL;
  21710. +               validate_all_references (regno, insn, XEXP (pat, 0));
  21711. +             }
  21712. +           return;
  21713. +         }
  21714. +       break;
  21715. +     }
  21716. +   fmt = GET_RTX_FORMAT (code);
  21717. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  21718. +     if (fmt[i] == 'e')
  21719. +       {
  21720. +         if( XEXP (pat, i))
  21721. +           validate_all_references (regno, insn, XEXP (pat, i));
  21722. +       }
  21723. +     else if (fmt[i] == 'E' || fmt[i] == 'V')
  21724. +       {
  21725. +     for (j = 0; j < XVECLEN (pat, i); j++)
  21726. +           validate_all_references (regno, insn, XVECEXP (pat, i, j));
  21727. +       }
  21728. + }
  21729. + #define MAX_WHERE 5
  21730. + #define MAX_DISAMBIGS 3
  21731. + #define MAX_MEM_REFS 10
  21732. + #define NO_REG -1
  21733. + #define UNKNOWN -2
  21734. + static struct mem_ref {
  21735. +   /*  Pointers to where this mem_ref is used.  */
  21736. +   rtx * where[MAX_WHERE];
  21737. +   /* Number of references to this mem_ref in the loop.  */
  21738. +   int num_ref;
  21739. +   /* The base register number if any, else -1.  */
  21740. +   int base_regno;
  21741. +   /* The base register number if.  */
  21742. +   rtx base_reg;
  21743. +   /* The index register number if any, else -1.  */
  21744. +   int index_regno;
  21745. +   /* The index register number if.  */
  21746. +   rtx index_reg;
  21747. +   /* Bit-map if bit# i is set then this element is true_dependence on
  21748. +      element# i. Assumes MAX_MEM_REFS < (sizeof (int) * 8) */
  21749. +   int conflict;
  21750. +   /* If 1 then this element is a varying address over the loop - or
  21751. +      should not be lifted into register for some other reason.  */
  21752. +   unsigned int varying:1;
  21753. +   /* If 1 then this mem_ref is stored into in the loop.  */
  21754. +   unsigned int stored:1;
  21755. +   /* If 1 then the first reference to the mem_ref in the loop is a store.  */
  21756. +   unsigned int first_stored:1;
  21757. +   } *mem_refs;
  21758. + static struct disambig{
  21759. +   rtx reg;
  21760. +   int inc_val;
  21761. + }    runtime_disambigs [MAX_DISAMBIGS];
  21762. + static int num_mem_refs = 0;
  21763. + static int max_regs_before_lift;
  21764. + extern rtx gen_jump ();
  21765. + /*
  21766. +   Shadow memory locations that are stored into in the loop and can
  21767. +   be memory disambiguated over the loop. These are loaded into a register
  21768. +   before the loop, accessed from and into the register during the loop
  21769. +   and stored from the register at the loop end.  
  21770. + */
  21771. + static void
  21772. + lift_stores (loop_start, loop_end)
  21773. +   rtx loop_start, loop_end;
  21774. + {
  21775. +   rtx insn, lift_reg, set, new_label, new_label_insn, new_jump_insn, new_jump,
  21776. +       new_loop_label, new_loop_jump, new_compare, new_compare_insn, copy_insn;
  21777. +   int i, j, num_candidates, jmask, imask, num_lifted, num_possible,
  21778. +       indx_possible, num_runtime_disambigs, disambig_mask, found, dummy;
  21779. +   char * may_not_optimize;
  21780. +   
  21781. +   if (loop_dump_stream)
  21782. +     {
  21783. +       fprintf (loop_dump_stream, "lift stores from %d to %d\n",
  21784. +       INSN_UID (loop_start), INSN_UID (loop_end));
  21785. +     }
  21786. +   /* Handle only loops with no inner jumps labels or calls */
  21787. +   if (GET_CODE (PREV_INSN (loop_end)) != JUMP_INSN)
  21788. +     {
  21789. +       return;
  21790. +     }
  21791. +   if (GET_CODE (SET_SRC (PATTERN (PREV_INSN (loop_end)))) != IF_THEN_ELSE)
  21792. +     {
  21793. +       return;
  21794. +     }
  21795. +   if (GET_CODE (NEXT_INSN (loop_start)) != CODE_LABEL)
  21796. +     {
  21797. +       return;
  21798. +     }
  21799. +   for (insn = NEXT_INSN (NEXT_INSN (loop_start)); 
  21800. +        insn != PREV_INSN (loop_end); insn = NEXT_INSN (insn))
  21801. +     {
  21802. +       if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN
  21803. +           || GET_CODE (insn) == CODE_LABEL)
  21804. +         {
  21805. +           return;
  21806. +         }
  21807. +     }
  21808. +   /* Compute n_times_set */
  21809. +   max_regs_before_lift = max_reg_num () + 1;
  21810. +   n_times_set = (short *) alloca (max_regs_before_lift * sizeof (short));
  21811. +   bzero (n_times_set, max_regs_before_lift * sizeof (short));
  21812. +   may_not_optimize = (char *) alloca (max_regs_before_lift);    /* not used */
  21813. +   count_loop_regs_set (loop_start, loop_end, may_not_optimize, NULL,
  21814. +                &dummy, max_regs_before_lift);
  21815. +   mem_refs = (struct mem_ref *) alloca (sizeof (struct mem_ref) * MAX_MEM_REFS);
  21816. +   bzero (mem_refs, sizeof (struct mem_ref) * MAX_MEM_REFS);
  21817. +   /* Locate all memory refs into the mem_refs array.  */
  21818. +   num_mem_refs = 0;
  21819. +   for (insn = loop_start; insn != loop_end; insn = NEXT_INSN (insn))
  21820. +     {
  21821. +       if (GET_CODE (insn) == INSN)
  21822. +         {
  21823. +           mark_mem_refs (PATTERN (insn), &PATTERN (insn));
  21824. +           if (num_mem_refs >= MAX_MEM_REFS)
  21825. +             {
  21826. +               return;
  21827. +             }
  21828. +         }
  21829. +     }
  21830. +   if (num_mem_refs == 0)
  21831. +     {
  21832. +       return;
  21833. +     }
  21834. +   /* Check each non varying mem_ref against all others to see if it can
  21835. +      be memory disambiguated */
  21836. +   num_candidates = 0;
  21837. +   for (i = 0; i < num_mem_refs; i++)
  21838. +     {
  21839. +       if (mem_refs[i].varying == 0 && mem_refs[i].stored == 1)
  21840. +         {
  21841. +           num_candidates++;
  21842. +           imask = 1 << i;
  21843. +           for (j = 0; j < num_mem_refs; j++)
  21844. +             {
  21845. +               jmask = (1 << j);
  21846. +               if (j != i && !(mem_refs[i].conflict & jmask))
  21847. +                 {
  21848. +                   if (true_dependence (*(mem_refs[i].where[0]),
  21849. +                                        *(mem_refs[j].where[0])))
  21850. +                     {
  21851. +                       mem_refs[i].conflict |= jmask;
  21852. +                       mem_refs[j].conflict |= imask;
  21853. +                     }
  21854. +                 }
  21855. +             }
  21856. +         }
  21857. +     }
  21858. +   /* Lift all the mem_refs that can be lifted.  */
  21859. +   num_lifted = 0;
  21860. +   num_possible = 0;
  21861. +   for (i = 0; i < num_mem_refs; i++)
  21862. +     {
  21863. +       if (mem_refs[i].varying == 0 && mem_refs[i].stored == 1)
  21864. +         {
  21865. +           num_possible++;
  21866. +           indx_possible = i;
  21867. +         }
  21868. +       if (mem_refs[i].varying == 0 && mem_refs[i].stored == 1
  21869. +           && mem_refs[i].conflict == 0)
  21870. +         {
  21871. +           num_lifted++;
  21872. +           lift_reg = gen_reg_rtx (GET_MODE (*(mem_refs[i].where[0])));
  21873. +           if (mem_refs[i].first_stored)
  21874. +             {
  21875. +               emit_insn_before ( gen_rtx (SET, 0, lift_reg, 
  21876. +                                           CONST0_RTX ( GET_MODE (lift_reg))),
  21877. +                                  loop_start);
  21878. +             }
  21879. +           else
  21880. +             {
  21881. +               emit_insn_before ( gen_rtx (SET, 0, lift_reg, 
  21882. +                                           copy_rtx (*(mem_refs[i].where[0]))),
  21883. +                                  loop_start);
  21884. +             }
  21885. +           emit_insn_after ( gen_rtx (SET, 0, copy_rtx (*(mem_refs[i].where[0])),
  21886. +                                               lift_reg),
  21887. +                                  loop_end);
  21888. +           /*emit_insn_after (gen_rtx (USE, 0, lift_reg),
  21889. +                           NEXT_INSN (loop_end));*/
  21890. +           for (j = 0; j < mem_refs[i].num_ref; j++)
  21891. +             {
  21892. +               *(mem_refs[i].where[j]) = lift_reg;
  21893. +             }
  21894. +           if (loop_dump_stream)
  21895. +             {
  21896. +               fprintf (loop_dump_stream, 
  21897. +               "The following memory operand lifted into reg %d during loop:\n",
  21898. +               REGNO (lift_reg));
  21899. +               tdebug_rtx (SET_DEST (PATTERN (NEXT_INSN (loop_end))),
  21900. +                           loop_dump_stream);
  21901. +               fprintf (loop_dump_stream, "\n");
  21902. +             }
  21903. +         }
  21904. +     }
  21905. +   if (num_lifted == 0 && num_possible == 1 && flag_runtime_lift_stores)
  21906. +     {  /* Do runtime disambiguation if possible */
  21907. +       if (mem_refs[indx_possible].index_regno != NO_REG
  21908. +           || mem_refs[indx_possible].base_regno == NO_REG
  21909. +           || mem_refs[indx_possible].base_regno == UNKNOWN)
  21910. +         {
  21911. +           return;
  21912. +         }
  21913. +       if (GET_MODE (mem_refs[indx_possible].base_reg) != SImode)
  21914. +         {
  21915. +           return;
  21916. +         }
  21917. +       num_runtime_disambigs = 0;
  21918. +       for (i = 0; i < num_mem_refs; i++)
  21919. +         {
  21920. +           disambig_mask = 1 << i;
  21921. +           if (mem_refs[indx_possible].conflict & disambig_mask)
  21922. +             {
  21923. +               if (num_runtime_disambigs >= MAX_DISAMBIGS)
  21924. +                 {
  21925. +                   return;
  21926. +                 }
  21927. +               if (mem_refs[i].base_regno == NO_REG 
  21928. +                   || mem_refs[i].base_regno == UNKNOWN
  21929. +                   || (mem_refs[i].index_regno != UNKNOWN
  21930. +                       && mem_refs[i].index_regno != NO_REG))
  21931. +                 {
  21932. +                   return;
  21933. +                 }
  21934. +               if (n_times_set[mem_refs[i].base_regno] > 1)
  21935. +                 {
  21936. +                   return;
  21937. +                 }
  21938. +               if (GET_MODE (mem_refs[i].base_reg) 
  21939. +                    != GET_MODE (mem_refs[indx_possible].base_reg))
  21940. +                 {
  21941. +                   return;
  21942. +                 }
  21943. +               runtime_disambigs[num_runtime_disambigs].reg
  21944. +                 = mem_refs[i].base_reg;
  21945. +               runtime_disambigs[num_runtime_disambigs].inc_val = 0;
  21946. +               num_runtime_disambigs++;
  21947. +             }
  21948. +         }
  21949. +       /* Now find the setting of each of the registers of the disambigs */
  21950. +       for (i = 0; i < num_runtime_disambigs; i++)
  21951. +         {
  21952. +           if (n_times_set[REGNO (runtime_disambigs[i].reg)])
  21953. +             {
  21954. +               insn = loop_start;
  21955. +               found = 0;
  21956. +               while (insn != loop_end && !found)
  21957. +                 {
  21958. +                   if (GET_CODE (insn) == INSN)
  21959. +                     {
  21960. +                       set = single_set (insn);
  21961. +                       if (set && GET_CODE (SET_DEST (set)) == REG
  21962. +                           && REGNO (SET_DEST (set)) 
  21963. +                               == REGNO (runtime_disambigs[i].reg) )
  21964. +                         {
  21965. +                           found = 1;
  21966. +                           if (!rtx_equal_p (SET_DEST (set),
  21967. +                                             runtime_disambigs[i].reg))
  21968. +                             {
  21969. +                               return;
  21970. +                             }
  21971. +                           if ((GET_CODE (SET_SRC (set)) == PLUS
  21972. +                                 || GET_CODE (SET_SRC (set)) == MINUS)
  21973. +                               && rtx_equal_p (SET_DEST (set), 
  21974. +                                               XEXP (SET_SRC (set), 0))
  21975. +                               && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
  21976. +                             {
  21977. +                               runtime_disambigs[i].inc_val 
  21978. +                                 = XINT (XEXP (SET_SRC (set), 1), 0) 
  21979. +                                    * (GET_CODE (SET_SRC (set)) == PLUS
  21980. +                                       ? 1 : -1);
  21981. +                             }
  21982. +                           else
  21983. +                             {
  21984. +                               return;
  21985. +                             }
  21986. +                         }
  21987. +                     }
  21988. +                   if (!found)
  21989. +                     {
  21990. +                       insn = NEXT_INSN (insn);
  21991. +                     }
  21992. +                 }
  21993. +               if (!found)
  21994. +                 {
  21995. +                   return;
  21996. +                 }
  21997. +             }
  21998. +         }
  21999. +       /* The runtime disambiguation is possible - now do it.  */
  22000. +       /* Make a copy of the loop.  */
  22001. +       new_label = gen_label_rtx ();
  22002. +       new_label_insn 
  22003. +         = emit_label_after (new_label, PREV_INSN (loop_start));
  22004. +       new_loop_label = new_label_insn;
  22005. +       ++LABEL_NUSES (new_label_insn);
  22006. +       new_jump = copy_rtx (PATTERN (PREV_INSN (loop_end)));
  22007. +       if (XEXP (SET_SRC (new_jump), 1) == pc_rtx)
  22008. +         {
  22009. +           XEXP (SET_SRC (new_jump), 2)
  22010. +             = gen_rtx (LABEL_REF, VOIDmode, new_label);
  22011. +         }
  22012. +       else
  22013. +         {
  22014. +           XEXP (SET_SRC (new_jump), 1)
  22015. +             = gen_rtx (LABEL_REF, VOIDmode, new_label);
  22016. +         }
  22017. +       new_jump_insn = emit_jump_insn_after (new_jump, new_label_insn);
  22018. +       INSN_CODE (new_jump_insn) = recog (new_jump, new_jump_insn);
  22019. +       new_loop_jump = new_jump_insn;
  22020. +       JUMP_LABEL (new_jump_insn) = new_label_insn;
  22021. +       /* The body of the original loop is moved to the new loop */
  22022. +       NEXT_INSN (new_label_insn) = NEXT_INSN (NEXT_INSN (loop_start));
  22023. +       PREV_INSN (NEXT_INSN (new_label_insn)) = new_label_insn;
  22024. +       PREV_INSN (new_jump_insn) = PREV_INSN (PREV_INSN (loop_end));
  22025. +       NEXT_INSN ( PREV_INSN (new_jump_insn)) = new_jump_insn;
  22026. +       NEXT_INSN (NEXT_INSN (loop_start)) = PREV_INSN (loop_end);
  22027. +       PREV_INSN (PREV_INSN (loop_end)) = NEXT_INSN (loop_start);
  22028. +       /* Now make a copy of the loop in between the original label and jump.  */
  22029. +       insn = NEXT_INSN (new_label_insn);
  22030. +       copy_insn = NEXT_INSN (loop_start);
  22031. +       while (insn != new_jump_insn)
  22032. +         {
  22033. +           if (GET_CODE (insn) == INSN)
  22034. +             {
  22035. +               copy_insn = emit_insn_after (copy_rtx (PATTERN (insn)), copy_insn);
  22036. +             }
  22037. +           insn = NEXT_INSN (insn);
  22038. +         }
  22039. +       /* Now make a jump around the second copy of the loop.  */
  22040. +       new_label = gen_label_rtx ();
  22041. +       new_label_insn 
  22042. +         = emit_label_after (new_label, loop_end);
  22043. +       new_jump_insn = emit_jump_insn_after (gen_jump (new_label_insn),
  22044. +           PREV_INSN (loop_start));
  22045. +       JUMP_LABEL (new_jump_insn) = new_label_insn;
  22046. +       ++LABEL_NUSES (new_label_insn);
  22047. +       emit_barrier_after (new_jump_insn);
  22048. +       /* Now make a label just before loop start */
  22049. +       new_label = gen_label_rtx ();
  22050. +       new_label_insn 
  22051. +         = emit_label_after (new_label, PREV_INSN (loop_start));
  22052. +       ++LABEL_NUSES (new_label_insn);
  22053. +       /* Now compare the base_reg of the mem_ref to be lifted with
  22054. +          each of the base_regs that it conflicts with.  Jump around the
  22055. +          disambiguated loop if they conflict at runtime.  */
  22056. +       for (i = 0; i < num_runtime_disambigs; i++)
  22057. +         {
  22058. +           if (runtime_disambigs[i].inc_val != 0)
  22059. +             {
  22060. +               new_compare 
  22061. +                 = gen_cmpsi_1 (runtime_disambigs[i].reg,
  22062. +                                 mem_refs[indx_possible].base_reg);
  22063. +               new_compare_insn 
  22064. +                 = emit_insn_before (new_compare, new_loop_label);
  22065. +               new_jump = copy_rtx (new_jump);
  22066. +               if (runtime_disambigs[i].inc_val > 0)
  22067. +                 {
  22068. +                   GET_CODE (XEXP (SET_SRC (new_jump), 0)) = LE;
  22069. +                 }
  22070. +               else
  22071. +                 {
  22072. +                   GET_CODE (XEXP (SET_SRC (new_jump), 0)) = GE;
  22073. +                 }
  22074. +           XEXP (SET_SRC (new_jump), 1) 
  22075. +             = gen_rtx (LABEL_REF, VOIDmode, new_label);
  22076. +           XEXP (SET_SRC (new_jump), 2) = pc_rtx;
  22077. +               ++LABEL_NUSES (new_label_insn);
  22078. +               new_jump_insn 
  22079. +                 = emit_jump_insn_after (new_jump, new_compare_insn);
  22080. +               JUMP_LABEL (new_jump_insn) = new_label_insn;
  22081. +               INSN_CODE (new_jump_insn)
  22082. +                 = recog (new_jump, new_jump_insn);
  22083. +             }
  22084. +         }
  22085. +       /* Now do the lifting */
  22086. +       lift_reg = gen_reg_rtx (GET_MODE (*(mem_refs[indx_possible].where[0])));
  22087. +       if (mem_refs[indx_possible].first_stored)
  22088. +         {
  22089. +           emit_insn_before ( gen_rtx (SET, 0, lift_reg, 
  22090. +                                       CONST0_RTX ( GET_MODE (lift_reg))),
  22091. +                              new_loop_label);
  22092. +         }
  22093. +       else
  22094. +         {
  22095. +           emit_insn_before ( gen_rtx (SET, 0, lift_reg, 
  22096. +                             copy_rtx (*(mem_refs[indx_possible].where[0]))),
  22097. +                              new_loop_label);
  22098. +         }
  22099. +       emit_insn_after ( gen_rtx (SET, 0, 
  22100. +                                  copy_rtx (*(mem_refs[indx_possible].where[0])),
  22101. +                                           lift_reg),
  22102. +                              new_loop_jump);
  22103. +       /*emit_insn_after (gen_rtx (USE, 0, lift_reg),
  22104. +                       NEXT_INSN (new_loop_jump));*/
  22105. +       emit_insn_after (gen_rtx (CLOBBER, 0, lift_reg), loop_end);
  22106. +       for (j = 0; j < mem_refs[indx_possible].num_ref; j++)
  22107. +         {
  22108. +           *(mem_refs[indx_possible].where[j]) = lift_reg;
  22109. +         }
  22110. +       emit_note_before (NOTE_INSN_LOOP_BEG, new_loop_label);
  22111. +       emit_note_before (NOTE_INSN_LOOP_END, NEXT_INSN (new_loop_jump));
  22112. +       if (loop_dump_stream)
  22113. +         {
  22114. +           fprintf (loop_dump_stream, 
  22115. +           "The following memory operand RUNTIME lifted into reg %d during loop:\n",
  22116. +           REGNO (lift_reg));
  22117. +           tdebug_rtx (SET_DEST (PATTERN (NEXT_INSN (NEXT_INSN (new_loop_jump)))),
  22118. +                       loop_dump_stream);
  22119. +           fprintf (loop_dump_stream, "\n");
  22120. +         }
  22121. +     }
  22122. + }
  22123. + /* 
  22124. +    Go over PAT locate all mem_refs and insert them into the mem_refs
  22125. +    structure.  WHERE is the location of PAT.  */
  22126. + static void 
  22127. + mark_mem_refs (pat, where)
  22128. +      rtx pat;
  22129. +      rtx *where;
  22130. + {
  22131. +   register RTX_CODE code = GET_CODE (pat);
  22132. +   register int i, j;
  22133. +   register char *fmt;
  22134. +   switch (code)
  22135. +     {
  22136. +     case HIGH:
  22137. +     case CONST_INT:
  22138. +     case CONST:
  22139. +     case CONST_DOUBLE:
  22140. +     case SYMBOL_REF:
  22141. +     case LABEL_REF:
  22142. +     case PC:
  22143. +     case CC0:
  22144. +       return ;
  22145. +     case SET:
  22146. +       mark_mem_refs (SET_SRC (pat), &SET_SRC (pat));
  22147. +       if (GET_CODE (SET_DEST (pat)) == MEM)
  22148. +         {
  22149. +           insert_mem_ref (SET_DEST (pat), &SET_DEST (pat), 1);
  22150. +         }
  22151. +       return;
  22152. +      case MEM:
  22153. +        insert_mem_ref (pat, where, 0);
  22154. +        return;
  22155. +     }
  22156. +   fmt = GET_RTX_FORMAT (code);
  22157. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  22158. +     if (fmt[i] == 'e')
  22159. +       {
  22160. +         if( XEXP (pat, i))
  22161. +           mark_mem_refs (XEXP (pat, i), &XEXP (pat, i));
  22162. +       }
  22163. +     else if (fmt[i] == 'E' || fmt[i] == 'V')
  22164. +       {
  22165. +     for (j = 0; j < XVECLEN (pat, i); j++)
  22166. +       mark_mem_refs (XVECEXP (pat, i, j), &XVECEXP (pat, i, j));
  22167. +       }
  22168. + }
  22169. + /*
  22170. +    Insert the memory reference MEM into the mem_refs structure.  
  22171. +    WHERE is location of MEM.  
  22172. +    if IS_STORE is 1 then MEM is being stored into.  */
  22173. +    
  22174. + static void
  22175. + insert_mem_ref (mem, where, is_store)
  22176. +   rtx mem, *where;
  22177. +   int is_store;
  22178. + {
  22179. +   int i, j, indx, found, base_regno, index_regno;
  22180. +   rtx mem_addr, base_reg, index_reg;
  22181. +   if (num_mem_refs >= MAX_MEM_REFS)
  22182. +     {
  22183. +       return;
  22184. +     }
  22185. +   /* Find where in table to put mem.  */
  22186. +   i = 0;
  22187. +   found = 0;
  22188. +   while (i < num_mem_refs && !found)
  22189. +     {
  22190. +       if (rtx_equal_p (mem, *(mem_refs[i].where[0])))
  22191. +         {
  22192. +           found = 1;
  22193. +         }
  22194. +       else
  22195. +         {
  22196. +           i++;
  22197. +         }
  22198. +     }
  22199. +   if (!found)
  22200. +     {
  22201. +       num_mem_refs++;
  22202. +     }
  22203. +   if (i >= MAX_MEM_REFS)
  22204. +     {
  22205. +       return;
  22206. +     }
  22207. +   indx = i;
  22208. +   j = mem_refs[indx].num_ref;
  22209. +   if (j >= MAX_WHERE)
  22210. +     {
  22211. +       mem_refs[indx].varying = 1;
  22212. +       return;
  22213. +     }
  22214. +   mem_refs[indx].where[j] = where;
  22215. +   mem_refs[indx].num_ref++;
  22216. +   if (is_store)
  22217. +     {
  22218. +       mem_refs[indx].stored = 1;
  22219. +       if (j == 0)
  22220. +         {
  22221. +           mem_refs[indx].first_stored = 1;
  22222. +         }
  22223. +     }
  22224. +   if (found == 1)
  22225. +     {
  22226. +       return;
  22227. +     }
  22228. +   mem_refs[indx].varying = rtx_addr_varies_p (mem);
  22229. +   /* Now analyze the mem to find it's base and index registers if any */
  22230. +   mem_refs[indx].base_regno = NO_REG;
  22231. +   mem_refs[indx].index_regno = NO_REG;
  22232. +   index_reg = NULL;
  22233. +   base_regno = NO_REG;
  22234. +   index_regno = NO_REG;
  22235. +   base_reg = NULL;
  22236. +   mem_addr = XEXP (mem, 0);
  22237. +   if (GET_CODE (mem_addr) == SYMBOL_REF)
  22238. +     {
  22239. +       return;
  22240. +     }
  22241. +   if (GET_CODE (mem_addr) == REG)
  22242. +     {
  22243. +       base_regno = REGNO (mem_addr);
  22244. +       base_reg = (mem_addr);
  22245. +     }
  22246. +   if (GET_CODE (mem_addr) == PLUS)
  22247. +     {
  22248. +       if (GET_CODE (XEXP (mem_addr, 0)) == REG)
  22249. +     {
  22250. +       base_regno = REGNO (XEXP (mem_addr, 0));
  22251. +       base_reg = (XEXP (mem_addr, 0));
  22252. +       if (GET_CODE (XEXP (mem_addr, 1)) == REG)
  22253. +         {
  22254. +           index_regno = REGNO (XEXP (mem_addr, 1));
  22255. +           index_reg = (XEXP (mem_addr, 1));
  22256. +         }
  22257. +       else if (GET_CODE (XEXP (mem_addr, 1)) != CONST_INT 
  22258. +                && GET_CODE (XEXP (mem_addr, 1)) != CONST
  22259. +                && GET_CODE (XEXP (mem_addr, 1)) != SYMBOL_REF)
  22260. +         {
  22261. +           index_regno = UNKNOWN;
  22262. +         }
  22263. +     }
  22264. +       else if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
  22265. +     {
  22266. +       if (GET_CODE (XEXP (mem_addr, 1)) == REG)
  22267. +         {
  22268. +           base_regno = REGNO (XEXP (mem_addr, 1));
  22269. +           base_reg =  (XEXP (mem_addr, 1));
  22270. +         }
  22271. +       else if (GET_CODE (XEXP (mem_addr, 1)) != CONST_INT 
  22272. +                && GET_CODE (XEXP (mem_addr, 1)) != CONST
  22273. +                && GET_CODE (XEXP (mem_addr, 1)) != SYMBOL_REF)
  22274. +         {
  22275. +           base_regno = UNKNOWN;
  22276. +         }
  22277. +       if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == REG
  22278. +           && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == CONST_INT)
  22279. +        {
  22280. +          index_regno = REGNO (XEXP (XEXP (mem_addr, 0), 0));
  22281. +          index_reg = (XEXP (XEXP (mem_addr, 0), 0));
  22282. +        }
  22283. +      else
  22284. +        {
  22285. +          index_regno = UNKNOWN;
  22286. +        }
  22287. +     }
  22288. +       else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
  22289. +     {
  22290. +           if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == REG)
  22291. +         {
  22292. +           base_regno = REGNO (XEXP (XEXP (mem_addr, 0), 0));
  22293. +           base_reg = (XEXP (XEXP (mem_addr, 0), 0));
  22294. +           if (GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG)
  22295. +             {
  22296. +               index_regno = REGNO (XEXP (XEXP (mem_addr, 0), 1));
  22297. +               index_reg = (XEXP (XEXP (mem_addr, 0), 1));
  22298. +             }
  22299. +                 else if (GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) != CONST_INT 
  22300. +                    && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) != CONST
  22301. +                    && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) != SYMBOL_REF)
  22302. +             {
  22303. +               index_regno = UNKNOWN;
  22304. +             }
  22305. +         }
  22306. +           else if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == MULT)
  22307. +         {
  22308. +           if (GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG)
  22309. +             {
  22310. +               base_regno = REGNO (XEXP (XEXP (mem_addr, 0), 1));
  22311. +               base_reg = (XEXP (XEXP (mem_addr, 0), 1));
  22312. +             }
  22313. +           if (GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == REG
  22314. +               && GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1)) == CONST_INT)
  22315. +            {
  22316. +              index_regno = REGNO (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0));
  22317. +              index_reg = (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0));
  22318. +            }
  22319. +          else
  22320. +            {
  22321. +              index_regno = UNKNOWN;
  22322. +            }
  22323. +         }
  22324. +       if (GET_CODE (XEXP (mem_addr, 1)) != SYMBOL_REF
  22325. +           && GET_CODE (XEXP (mem_addr, 1)) != CONST
  22326. +           && GET_CODE (XEXP (mem_addr, 1)) != CONST_INT)
  22327. +         {
  22328. +           index_regno = UNKNOWN;
  22329. +           base_regno = UNKNOWN;
  22330. +         }
  22331. +     }
  22332. +     }
  22333. +   else if (GET_CODE (mem_addr) == MULT)
  22334. +     {
  22335. +       if (GET_CODE (XEXP (mem_addr, 0)) == REG 
  22336. +           && GET_CODE (XEXP (mem_addr, 1)) == CONST_INT)
  22337. +         {
  22338. +           index_regno = REGNO (XEXP (mem_addr, 0));
  22339. +           index_reg = (XEXP (mem_addr, 0));
  22340. +         }
  22341. +       else
  22342. +         {
  22343. +           index_regno = UNKNOWN;
  22344. +         }
  22345. +     }
  22346. +   mem_refs[indx].base_reg = base_reg;
  22347. +   mem_refs[indx].base_regno = base_regno;
  22348. +   mem_refs[indx].index_reg = index_reg;
  22349. +   mem_refs[indx].index_regno = index_regno;
  22350. +   if (base_regno == UNKNOWN || index_regno == UNKNOWN)
  22351. +     {
  22352. +       mem_refs[indx].varying = 1;
  22353. +       return;
  22354. +     }
  22355. +   if (base_regno >= max_regs_before_lift || index_regno >= max_regs_before_lift)
  22356. +     {
  22357. +       mem_refs[indx].varying = 1;
  22358. +       return;
  22359. +     }
  22360. +   if ( (base_regno == NO_REG || n_times_set[base_regno] == 0)
  22361. +       && (index_regno == NO_REG || n_times_set[index_regno] == 0))
  22362. +     {
  22363. +       mem_refs[indx].varying = 0;
  22364. +     }
  22365. +   if (MEM_VOLATILE_P (mem))
  22366. +     {
  22367. +       mem_refs[indx].varying = 1;
  22368. +     }
  22369. + }
  22370. +  
  22371. + static void opt_reg_use_copy (f)
  22372. +   rtx f;
  22373. + {
  22374. +   rtx insn, src, prev;
  22375. +   int i, length;
  22376. +   char * fmt;
  22377. +   for (insn = f; insn; insn = NEXT_INSN (insn))
  22378. +     {
  22379. +       if (GET_CODE (insn) == INSN)
  22380. +         {
  22381. +         if (GET_CODE (PATTERN (insn)) == SET
  22382. +           && GET_CODE (SET_DEST (PATTERN (insn))) == REG
  22383. +           && GET_CODE (SET_SRC (PATTERN (insn))) == REG
  22384. +           && (prev = PREV_INSN (insn))
  22385. +           && GET_CODE (prev) == INSN
  22386. +           && GET_CODE (PATTERN (prev)) == SET
  22387. +           && rtx_equal_p (SET_SRC (PATTERN (insn)), 
  22388. +                           SET_DEST (PATTERN (prev))))
  22389. +         {
  22390. +               src = SET_SRC (PATTERN (prev));
  22391. +               fmt = GET_RTX_FORMAT (GET_CODE (src));
  22392. +               length = GET_RTX_LENGTH (GET_CODE (src));
  22393. +               for (i=0; i<length; i++)
  22394. +                 {
  22395. +                   if (fmt[i] == 'e' 
  22396. +                       && GET_CODE (XEXP (src, i)) == REG
  22397. +                       && rtx_equal_p (XEXP (src, i), SET_DEST (PATTERN (insn))))
  22398. +                     {  
  22399. +                       SET_DEST (PATTERN (insn)) = SET_SRC (PATTERN (insn));
  22400. +                       SET_SRC (PATTERN (insn)) = XEXP (src, i);
  22401. +                       SET_DEST (PATTERN (prev)) = XEXP (src, i);
  22402. +                       emit_insn_after (gen_rtx (USE, 0, 
  22403. +                                                 SET_DEST (PATTERN (prev))),
  22404. +                                        prev);
  22405. +                       break;
  22406. +                     }
  22407. +                 }
  22408. +         }
  22409. +     }
  22410. +     }
  22411.   }
  22412. diff -rNci gcc-2.7.2/loop.h gcc-2.7.2p/loop.h
  22413. *** gcc-2.7.2/loop.h    Fri Jul 14 12:23:28 1995
  22414. --- gcc-2.7.2p/loop.h    Tue Jan 23 09:25:29 1996
  22415. ***************
  22416. *** 88,93 ****
  22417. --- 88,97 ----
  22418.     unsigned maybe_dead : 1;    /* 1 if this giv might be dead.  In that case,
  22419.                      we won't use it to eliminate a biv, it
  22420.                      would probably lose. */
  22421. + #ifdef REDUCE_INDEX
  22422. +   unsigned is_index_induc:1; /* 1 if this is actually the index portion
  22423. +                                 of a DEST_ADDR g_type intel1 */
  22424. + #endif
  22425.     int lifetime;            /* Length of life of this giv */
  22426.     int times_used;        /* # times this giv is used. */
  22427.     rtx derive_adjustment;    /* If nonzero, is an adjustment to be
  22428. ***************
  22429. *** 133,138 ****
  22430. --- 137,144 ----
  22431.     unsigned nonneg : 1;        /* 1 if we added a REG_NONNEG note for this. */
  22432.     unsigned reversed : 1;    /* 1 if we reversed the loop that this
  22433.                      biv controls. */
  22434. +   unsigned retry_celim :2; /*intel1 is >0 if we should retry compare 
  22435. +                              elimination at the end of strength reduction */
  22436.   };
  22437.   
  22438.   /* Definitions used by the basic induction variable discovery code.  */
  22439. ***************
  22440. *** 146,152 ****
  22441.   extern int *uid_loop_num;
  22442.   extern int *loop_outer_loop;
  22443.   extern rtx *loop_number_exit_labels;
  22444. - extern int *loop_number_exit_count;
  22445.   extern unsigned HOST_WIDE_INT loop_n_iterations;
  22446.   extern int max_reg_before_loop;
  22447.   
  22448. --- 152,157 ----
  22449. diff -rNci gcc-2.7.2/obstack.c gcc-2.7.2p/obstack.c
  22450. *** gcc-2.7.2/obstack.c    Sun Nov 26 19:57:12 1995
  22451. --- gcc-2.7.2p/obstack.c    Thu Jun 15 22:12:08 1995
  22452. ***************
  22453. *** 17,46 ****
  22454.   
  22455.   #include "obstack.h"
  22456.   
  22457. ! /* NOTE BEFORE MODIFYING THIS FILE: This version number must be
  22458. !    incremented whenever callers compiled using an old obstack.h can no
  22459. !    longer properly call the functions in this obstack.c.  */
  22460. ! #define OBSTACK_INTERFACE_VERSION 1
  22461.   
  22462.   /* Comment out all this code if we are using the GNU C Library, and are not
  22463. !    actually compiling the library itself, and the installed library
  22464. !    supports the same library interface we do.  This code is part of the GNU
  22465. !    C Library, but also included in many other GNU distributions.  Compiling
  22466.      and linking in this code is a waste when using the GNU C library
  22467.      (especially if it is a shared library).  Rather than having every GNU
  22468. !    program understand `configure --with-gnu-libc' and omit the object
  22469. !    files, it is simpler to just do this in the source for each such file.  */
  22470.   
  22471. ! #include <stdio.h>        /* Random thing to get __GNU_LIBRARY__.  */
  22472. ! #if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
  22473. ! #include <gnu-versions.h>
  22474. ! #if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
  22475. ! #define ELIDE_CODE
  22476. ! #endif
  22477. ! #endif
  22478. ! #ifndef ELIDE_CODE
  22479.   
  22480.   
  22481.   #if defined (__STDC__) && __STDC__
  22482. --- 17,34 ----
  22483.   
  22484.   #include "obstack.h"
  22485.   
  22486. ! /* This is just to get __GNU_LIBRARY__ defined.  */
  22487. ! #include <stdio.h>
  22488.   
  22489.   /* Comment out all this code if we are using the GNU C Library, and are not
  22490. !    actually compiling the library itself.  This code is part of the GNU C
  22491. !    Library, but also included in many other GNU distributions.  Compiling
  22492.      and linking in this code is a waste when using the GNU C library
  22493.      (especially if it is a shared library).  Rather than having every GNU
  22494. !    program understand `configure --with-gnu-libc' and omit the object files,
  22495. !    it is simpler to just do this in the source for each such file.  */
  22496.   
  22497. ! #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
  22498.   
  22499.   
  22500.   #if defined (__STDC__) && __STDC__
  22501. ***************
  22502. *** 494,497 ****
  22503.   
  22504.   #endif /* 0 */
  22505.   
  22506. ! #endif    /* !ELIDE_CODE */
  22507. --- 482,485 ----
  22508.   
  22509.   #endif /* 0 */
  22510.   
  22511. ! #endif    /* _LIBC or not __GNU_LIBRARY__.  */
  22512. diff -rNci gcc-2.7.2/optabs.c gcc-2.7.2p/optabs.c
  22513. *** gcc-2.7.2/optabs.c    Sat Oct 21 22:16:13 1995
  22514. --- gcc-2.7.2p/optabs.c    Thu Jun 15 11:55:15 1995
  22515. ***************
  22516. *** 3511,3517 ****
  22517.             /* The sign bit is not set.  Convert as signed.  */
  22518.             expand_float (target, from, 0);
  22519.             emit_jump_insn (gen_jump (label));
  22520. -           emit_barrier ();
  22521.   
  22522.             /* The sign bit is set.
  22523.            Convert to a usable (positive signed) value by shifting right
  22524. --- 3511,3516 ----
  22525. diff -rNci gcc-2.7.2/output.h gcc-2.7.2p/output.h
  22526. *** gcc-2.7.2/output.h    Fri Jul 14 12:02:05 1995
  22527. --- gcc-2.7.2p/output.h    Thu Jun 15 11:55:44 1995
  22528. ***************
  22529. *** 376,386 ****
  22530.   
  22531.   extern int current_function_varargs;
  22532.   
  22533. - /* Nonzero if current function uses stdarg.h or equivalent.
  22534. -    Zero for functions that use varargs.h.  */
  22535. - extern int current_function_stdarg;
  22536.   /* Quantities of various kinds of registers
  22537.      used for the current function's args.  */
  22538.   
  22539. --- 376,381 ----
  22540. diff -rNci gcc-2.7.2/print-rtl.c gcc-2.7.2p/print-rtl.c
  22541. *** gcc-2.7.2/print-rtl.c    Thu Jun 15 11:56:24 1995
  22542. --- gcc-2.7.2p/print-rtl.c    Tue Jan 23 09:25:29 1996
  22543. ***************
  22544. *** 231,236 ****
  22545. --- 231,246 ----
  22546.     fprintf (stderr, "\n");
  22547.   }
  22548.   
  22549. + void
  22550. + tdebug_rtx(x, file)
  22551. +     rtx x;
  22552. +     FILE *file;
  22553. + {
  22554. +   outfile=file;
  22555. +   print_rtx(x);
  22556. +   fprintf(file, "\n");
  22557. + }
  22558.   /* Count of rtx's to print with debug_rtx_list.
  22559.      This global exists because gdb user defined commands have no arguments.  */
  22560.   
  22561. diff -rNci gcc-2.7.2/real.c gcc-2.7.2p/real.c
  22562. *** gcc-2.7.2/real.c    Tue Aug 15 21:57:18 1995
  22563. --- gcc-2.7.2p/real.c    Thu Jun 15 11:57:39 1995
  22564. ***************
  22565. *** 2635,2647 ****
  22566.        unsigned EMUSHORT *a, *b, *c;
  22567.   {
  22568.     unsigned EMUSHORT ai[NI], bi[NI];
  22569. !   int i, sign;
  22570.     EMULONG lt, lta, ltb;
  22571.   
  22572. - /* IEEE says if result is not a NaN, the sign is "-" if and only if
  22573. -    operands have opposite signs -- but flush -0 to 0 later if not IEEE.  */
  22574. -   sign = eisneg(a) ^ eisneg(b);
  22575.   #ifdef NANS
  22576.   /* Return any NaN input. */
  22577.     if (eisnan (a))
  22578. --- 2635,2643 ----
  22579.        unsigned EMUSHORT *a, *b, *c;
  22580.   {
  22581.     unsigned EMUSHORT ai[NI], bi[NI];
  22582. !   int i;
  22583.     EMULONG lt, lta, ltb;
  22584.   
  22585.   #ifdef NANS
  22586.   /* Return any NaN input. */
  22587.     if (eisnan (a))
  22588. ***************
  22589. *** 2659,2665 ****
  22590.         || (eisinf (a) && eisinf (b)))
  22591.       {
  22592.       mtherr ("ediv", INVALID);
  22593. !     enan (c, sign);
  22594.       return;
  22595.       }
  22596.   #endif
  22597. --- 2655,2661 ----
  22598.         || (eisinf (a) && eisinf (b)))
  22599.       {
  22600.       mtherr ("ediv", INVALID);
  22601. !     enan (c, eisneg (a) ^ eisneg (b));
  22602.       return;
  22603.       }
  22604.   #endif
  22605. ***************
  22606. *** 2667,2680 ****
  22607.   #ifdef INFINITY
  22608.     if (eisinf (b))
  22609.       {
  22610.         einfin (c);
  22611. !       goto divsign;
  22612.       }
  22613.   /* Anything else over infinity is zero. */
  22614.     if (eisinf (a))
  22615.       {
  22616.         eclear (c);
  22617. !       goto divsign;
  22618.       }
  22619.   #endif
  22620.     emovi (a, ai);
  22621. --- 2663,2680 ----
  22622.   #ifdef INFINITY
  22623.     if (eisinf (b))
  22624.       {
  22625. +       if (eisneg (a) ^ eisneg (b))
  22626. +     *(c + (NE - 1)) = 0x8000;
  22627. +       else
  22628. +     *(c + (NE - 1)) = 0;
  22629.         einfin (c);
  22630. !       return;
  22631.       }
  22632.   /* Anything else over infinity is zero. */
  22633.     if (eisinf (a))
  22634.       {
  22635.         eclear (c);
  22636. !       return;
  22637.       }
  22638.   #endif
  22639.     emovi (a, ai);
  22640. ***************
  22641. *** 2692,2698 ****
  22642.           }
  22643.       }
  22644.         eclear (c);
  22645. !       goto divsign;
  22646.       }
  22647.    dnzro1:
  22648.   
  22649. --- 2692,2698 ----
  22650.           }
  22651.       }
  22652.         eclear (c);
  22653. !       return;
  22654.       }
  22655.    dnzro1:
  22656.   
  22657. ***************
  22658. *** 2706,2716 ****
  22659.             goto dnzro2;
  22660.           }
  22661.       }
  22662.   /* Divide by zero is not an invalid operation.
  22663.      It is a divide-by-zero operation!   */
  22664.         einfin (c);
  22665.         mtherr ("ediv", SING);
  22666. !       goto divsign;
  22667.       }
  22668.    dnzro2:
  22669.   
  22670. --- 2706,2720 ----
  22671.             goto dnzro2;
  22672.           }
  22673.       }
  22674. +       if (ai[0] == bi[0])
  22675. +     *(c + (NE - 1)) = 0;
  22676. +       else
  22677. +     *(c + (NE - 1)) = 0x8000;
  22678.   /* Divide by zero is not an invalid operation.
  22679.      It is a divide-by-zero operation!   */
  22680.         einfin (c);
  22681.         mtherr ("ediv", SING);
  22682. !       return;
  22683.       }
  22684.    dnzro2:
  22685.   
  22686. ***************
  22687. *** 2718,2735 ****
  22688.     /* calculate exponent */
  22689.     lt = ltb - lta + EXONE;
  22690.     emdnorm (bi, i, 0, lt, 64);
  22691. !   emovo (bi, c);
  22692. !  divsign:
  22693. !   if (sign
  22694. ! #ifndef IEEE
  22695. !       && (ecmp (c, ezero) != 0)
  22696. ! #endif
  22697. !       )
  22698. !      *(c+(NE-1)) |= 0x8000;
  22699.     else
  22700. !      *(c+(NE-1)) &= ~0x8000;
  22701.   }
  22702.   
  22703.   /* Multiply e-types A and B, return e-type product C.   */
  22704. --- 2722,2733 ----
  22705.     /* calculate exponent */
  22706.     lt = ltb - lta + EXONE;
  22707.     emdnorm (bi, i, 0, lt, 64);
  22708. !   /* set the sign */
  22709. !   if (ai[0] == bi[0])
  22710. !     bi[0] = 0;
  22711.     else
  22712. !     bi[0] = 0Xffff;
  22713. !   emovo (bi, c);
  22714.   }
  22715.   
  22716.   /* Multiply e-types A and B, return e-type product C.   */
  22717. ***************
  22718. *** 2739,2751 ****
  22719.        unsigned EMUSHORT *a, *b, *c;
  22720.   {
  22721.     unsigned EMUSHORT ai[NI], bi[NI];
  22722. !   int i, j, sign;
  22723.     EMULONG lt, lta, ltb;
  22724.   
  22725. - /* IEEE says if result is not a NaN, the sign is "-" if and only if
  22726. -    operands have opposite signs -- but flush -0 to 0 later if not IEEE.  */
  22727. -   sign = eisneg(a) ^ eisneg(b);
  22728.   #ifdef NANS
  22729.   /* NaN times anything is the same NaN. */
  22730.     if (eisnan (a))
  22731. --- 2737,2745 ----
  22732.        unsigned EMUSHORT *a, *b, *c;
  22733.   {
  22734.     unsigned EMUSHORT ai[NI], bi[NI];
  22735. !   int i, j;
  22736.     EMULONG lt, lta, ltb;
  22737.   
  22738.   #ifdef NANS
  22739.   /* NaN times anything is the same NaN. */
  22740.     if (eisnan (a))
  22741. ***************
  22742. *** 2763,2769 ****
  22743.         || (eisinf (b) && (ecmp (a, ezero) == 0)))
  22744.       {
  22745.       mtherr ("emul", INVALID);
  22746. !     enan (c, sign);
  22747.       return;
  22748.       }
  22749.   #endif
  22750. --- 2757,2763 ----
  22751.         || (eisinf (b) && (ecmp (a, ezero) == 0)))
  22752.       {
  22753.       mtherr ("emul", INVALID);
  22754. !     enan (c, eisneg (a) ^ eisneg (b));
  22755.       return;
  22756.       }
  22757.   #endif
  22758. ***************
  22759. *** 2771,2778 ****
  22760.   #ifdef INFINITY
  22761.     if (eisinf (a) || eisinf (b))
  22762.       {
  22763.         einfin (c);
  22764. !       goto mulsign;
  22765.       }
  22766.   #endif
  22767.     emovi (a, ai);
  22768. --- 2765,2776 ----
  22769.   #ifdef INFINITY
  22770.     if (eisinf (a) || eisinf (b))
  22771.       {
  22772. +       if (eisneg (a) ^ eisneg (b))
  22773. +     *(c + (NE - 1)) = 0x8000;
  22774. +       else
  22775. +     *(c + (NE - 1)) = 0;
  22776.         einfin (c);
  22777. !       return;
  22778.       }
  22779.   #endif
  22780.     emovi (a, ai);
  22781. ***************
  22782. *** 2790,2796 ****
  22783.           }
  22784.       }
  22785.         eclear (c);
  22786. !       goto mulsign;
  22787.       }
  22788.    mnzer1:
  22789.   
  22790. --- 2788,2794 ----
  22791.           }
  22792.       }
  22793.         eclear (c);
  22794. !       return;
  22795.       }
  22796.    mnzer1:
  22797.   
  22798. ***************
  22799. *** 2805,2811 ****
  22800.           }
  22801.       }
  22802.         eclear (c);
  22803. !       goto mulsign;
  22804.       }
  22805.    mnzer2:
  22806.   
  22807. --- 2803,2809 ----
  22808.           }
  22809.       }
  22810.         eclear (c);
  22811. !       return;
  22812.       }
  22813.    mnzer2:
  22814.   
  22815. ***************
  22816. *** 2814,2831 ****
  22817.     /* calculate exponent */
  22818.     lt = lta + ltb - (EXONE - 1);
  22819.     emdnorm (bi, j, 0, lt, 64);
  22820. !   emovo (bi, c);
  22821. !  mulsign:
  22822. !   if (sign
  22823. ! #ifndef IEEE
  22824. !       && (ecmp (c, ezero) != 0)
  22825. ! #endif
  22826. !       )
  22827. !      *(c+(NE-1)) |= 0x8000;
  22828.     else
  22829. !      *(c+(NE-1)) &= ~0x8000;
  22830.   }
  22831.   
  22832.   /* Convert double precision PE to e-type Y.  */
  22833. --- 2812,2823 ----
  22834.     /* calculate exponent */
  22835.     lt = lta + ltb - (EXONE - 1);
  22836.     emdnorm (bi, j, 0, lt, 64);
  22837. !   /* calculate sign of product */
  22838. !   if (ai[0] == bi[0])
  22839. !     bi[0] = 0;
  22840.     else
  22841. !     bi[0] = 0xffff;
  22842. !   emovo (bi, c);
  22843.   }
  22844.   
  22845.   /* Convert double precision PE to e-type Y.  */
  22846. diff -rNci gcc-2.7.2/recog.c gcc-2.7.2p/recog.c
  22847. *** gcc-2.7.2/recog.c    Sat Jul  1 10:52:35 1995
  22848. --- gcc-2.7.2p/recog.c    Thu Jun 15 11:58:34 1995
  22849. ***************
  22850. *** 864,880 ****
  22851.        reg went on the stack.)  */
  22852.         if (! reload_completed && GET_CODE (SUBREG_REG (op)) == MEM)
  22853.       return general_operand (op, mode);
  22854. - #ifdef CLASS_CANNOT_CHANGE_SIZE
  22855. -       if (GET_CODE (SUBREG_REG (op)) == REG
  22856. -       && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER
  22857. -       && TEST_HARD_REG_BIT (reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE],
  22858. -                 REGNO (SUBREG_REG (op)))
  22859. -       && (GET_MODE_SIZE (mode)
  22860. -           != GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))))
  22861. -     return 0;
  22862. - #endif
  22863.         op = SUBREG_REG (op);
  22864.       }
  22865.   
  22866. --- 864,869 ----
  22867. diff -rNci gcc-2.7.2/reg-stack.c gcc-2.7.2p/reg-stack.c
  22868. *** gcc-2.7.2/reg-stack.c    Thu Jun 15 21:36:05 1995
  22869. --- gcc-2.7.2p/reg-stack.c    Tue Jan 23 09:25:29 1996
  22870. ***************
  22871. *** 230,235 ****
  22872. --- 230,238 ----
  22873.     ((INSN_UID (INSN) > max_uid)    \
  22874.      ? (abort() , -1) : block_number[INSN_UID (INSN)])
  22875.   
  22876. + /* intel1 */
  22877. + extern FILE *stack_reg_dump_file;
  22878.   extern rtx forced_labels;
  22879.   extern rtx gen_jump ();
  22880.   extern rtx gen_movdf (), gen_movxf ();
  22881. ***************
  22882. *** 2121,2126 ****
  22883. --- 2124,2131 ----
  22884.       replace_reg (dest, FIRST_STACK_REG);
  22885.       break;
  22886.   
  22887. +       /* intel1 */
  22888. +       case FLOAT_EXTEND:
  22889.         case REG:
  22890.       /* This is a `tstM2' case. */
  22891.       if (*dest != cc0_rtx)
  22892. ***************
  22893. *** 3131,3134 ****
  22894. --- 3136,5348 ----
  22895.         fprintf (file, "\n");
  22896.       }
  22897.   }
  22898. + /* intel1 */
  22899. + #ifdef IS_STACK_MODE
  22900. + #include "basic-block.h"
  22901. + #include "obstack.h"
  22902. + #define obstack_chunk_alloc xmalloc
  22903. + #define obstack_chunk_free free
  22904. + extern int regset_bytes;
  22905. + extern struct obstack momentary_obstack;
  22906. + extern rtx *regno_reg_rtx;
  22907. + extern int max_regno;
  22908. + static void func_stack_reg_to_stack_slot ();
  22909. + static void bb_stack_reg_to_stack_slot ();
  22910. + void float_to_int_cmp ();
  22911. + static void offload_if_necessary ();
  22912. + static void offload_reg ();
  22913. + static void replace_with_stack_slot ();
  22914. + static int stack_reg_dies_at_store ();
  22915. + static void mark_stack_regs_mentioned ();
  22916. + static void replace_with_temp_slot ();
  22917. + static int reg_dead_at_pred ();
  22918. + static int reg_only_set_or_stored ();
  22919. + static int reg_used_in_body ();
  22920. + static int store_into_temp ();
  22921. + static int visit_till_dies ();
  22922. + static int addr_or_val_changed ();
  22923. + static void find_regs_mentioned ();
  22924. + static int tests_equality ();
  22925. + static int reg_last_loaded ();
  22926. + static int reg_def_in_unvisited ();
  22927. + static rtx reg_dies_in_block ();
  22928. + static int death_blocks_ok ();
  22929. + /* For each basic block the union of the basic_block_live_at_start
  22930. +    of each of it's successors.  */
  22931. + regset *basic_block_maybe_live_at_end;
  22932. + /* To mark each block visited on a path */
  22933. + char *blocks_visited;
  22934. + /* To mark those blocks on the path where the reg dies.
  22935. +    It is set to the NEXT_INSN of the insn in the block where
  22936. +    the reg dies */
  22937. + rtx *death_blocks;
  22938. + /* To mark those blocks where the reg is defined */
  22939. + char *blocks_defined;
  22940. + /* For finding block sucessors */
  22941. + int *fall_thru_block, *jump_target_block;
  22942. + /* The temp slots allocated to stack regs */
  22943. + rtx *reg_temp_slot;
  22944. + int num_visits;
  22945. + /* Information collected for optimizing use of stack regs
  22946. +    within a basic block
  22947. + */
  22948. + struct stack_reg_infos
  22949. +   {
  22950. +     rtx store_insn;
  22951. +     rtx non_dead_store[3];
  22952. +     rtx last_use;
  22953. +     unsigned char num_non_dead_store;
  22954. +     unsigned char dies_at_store;
  22955. +   }
  22956. +  *stack_reg_info;
  22957. + static
  22958. + struct regs_mentioned
  22959. +   {
  22960. +     rtx reg;
  22961. +     struct regs_mentioned *next;
  22962. +   } *reg_mentioned_header;
  22963. + void init_regset_vector ();
  22964. + void
  22965. + opt_reg_stack ()
  22966. + {
  22967. +   reg_temp_slot = (rtx *) alloca (max_regno * sizeof (rtx));
  22968. +   bzero (reg_temp_slot, max_regno * sizeof (rtx));
  22969. +   if (stack_reg_dump_file)
  22970. +     {
  22971. +       fprintf (stack_reg_dump_file," MAX_REGNO at start %d\n",max_regno);
  22972. +     }
  22973. +   func_stack_reg_to_stack_slot ();
  22974. +   bb_stack_reg_to_stack_slot ();
  22975. + #ifdef SPARE_REGS
  22976. +   max_regno = max_reg_num();
  22977. +   if (stack_reg_dump_file)
  22978. +     {
  22979. +       fprintf (stack_reg_dump_file," MAX_REGNO at end %d\n",max_regno);
  22980. +     }
  22981. + #endif
  22982. + }
  22983. + /*
  22984. +    Stack mode registers that are used only to move values
  22985. +    in a basic block are replaced with stack slots.
  22986. +    We also have something like this for between basic blocks
  22987. +    see the ear spec agc()/earfilters.c the last loop
  22988. + */
  22989. + static void
  22990. + bb_stack_reg_to_stack_slot ()
  22991. + {
  22992. +   int block, nregs, stack_regno, num_calls;
  22993. +   rtx insn;
  22994. +   nregs = max_regno;
  22995. +   stack_reg_info = (struct stack_reg_infos *)
  22996. +     alloca (nregs * sizeof (struct stack_reg_infos));
  22997. +   for (block = 0; block < n_basic_blocks; block++)
  22998. +     {
  22999. +       bzero (stack_reg_info, nregs * sizeof (struct stack_reg_infos));
  23000. +       num_calls = 0;
  23001. +       for (insn = basic_block_end[block];
  23002. +        insn && insn != PREV_INSN (basic_block_head[block]);
  23003. +        insn = PREV_INSN (insn))
  23004. +     {
  23005. +       if (GET_CODE (insn) == CALL_INSN)
  23006. +         num_calls++;
  23007. +       if (GET_CODE (insn) == INSN)
  23008. +         {
  23009. +           if (GET_CODE (PATTERN (insn)) != SET)
  23010. +         {
  23011. +           if (GET_CODE (PATTERN (insn)) == PARALLEL)
  23012. +             {
  23013. +               if (flag_do_offload)
  23014. +             offload_if_necessary (insn, block);
  23015. +             }
  23016. +           bzero (stack_reg_info, nregs * sizeof (struct stack_reg_infos));
  23017. +         }
  23018. +           else
  23019. +         {
  23020. +           if (GET_CODE (SET_DEST (PATTERN (insn))) == REG
  23021. +               && GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
  23022. +               && GET_CODE (SET_SRC (PATTERN (insn))) == FLOAT_TRUNCATE)
  23023. +             {
  23024. +               rtx slot;
  23025. +               slot 
  23026. +                 = assign_stack_local (SFmode, GET_MODE_SIZE (SFmode), -1);
  23027. +               emit_insn_after (gen_rtx (SET, 0, SET_DEST (PATTERN (insn)),
  23028. +                                         slot), insn);
  23029. +               SET_DEST (PATTERN (insn)) = slot;
  23030. +             }
  23031. +           stack_regno = -1;
  23032. +           if (stack_reg_dies_at_store (insn, &stack_regno))
  23033. +             { /* A store of stack_regno at which it dies.  */
  23034. +               stack_reg_info[stack_regno].dies_at_store = 1;
  23035. +               stack_reg_info[stack_regno].store_insn = insn;
  23036. +               stack_reg_info[stack_regno].num_non_dead_store = 0;
  23037. +             }
  23038. +           else if (stack_regno != -1)
  23039. +             {
  23040. +               /* Stored but not dead.  */
  23041. +               stack_reg_info[stack_regno].num_non_dead_store++;
  23042. +               if (stack_reg_info[stack_regno].num_non_dead_store <= 3)
  23043. +             {
  23044. +               stack_reg_info[stack_regno].non_dead_store
  23045. +                 [stack_reg_info[stack_regno].num_non_dead_store - 1] 
  23046. +                 = insn;
  23047. +             }
  23048. +               else
  23049. +             {
  23050. +               stack_reg_info[stack_regno].dies_at_store = 0;
  23051. +               stack_reg_info[stack_regno].store_insn = NULL;
  23052. +               stack_reg_info[stack_regno].last_use = NULL;
  23053. +               stack_reg_info[stack_regno].num_non_dead_store = 0;
  23054. +             }
  23055. +             }
  23056. +           else
  23057. +             mark_stack_regs_mentioned (SET_SRC (PATTERN (insn)), insn);
  23058. +           if (GET_CODE (SET_DEST (PATTERN (insn))) != REG)
  23059. +             mark_stack_regs_mentioned (SET_DEST (PATTERN (insn)), insn);
  23060. +           if (GET_CODE (SET_DEST (PATTERN (insn))) == REG
  23061. +               && IS_STACK_MODE (GET_MODE (SET_DEST (PATTERN (insn))))
  23062. +             )
  23063. +             { /* A setting of a stack register.  */
  23064. +               if (((GET_CODE (SET_SRC (PATTERN (insn))) == MEM
  23065. +                  && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn))))
  23066. +                || GET_CODE (SET_SRC (PATTERN (insn))) == CONST_DOUBLE)
  23067. +               && stack_reg_info[REGNO (SET_DEST (PATTERN (insn)))].dies_at_store)
  23068. +             { /* It is loaded from a non volatile memory and
  23069. +                  was stored upon death later in the basic block,
  23070. +                  try to do this NOT via the register stack.  */
  23071. +               replace_with_stack_slot (insn, block, num_calls);
  23072. +             }
  23073. +               else
  23074. +             { /* Just try to optimize consecutive stores and
  23075. +                  restart the information gathering.  
  23076. +               */
  23077. +               stack_regno = REGNO (SET_DEST (PATTERN (insn)));
  23078. +               opt_consec_stores (stack_regno);
  23079. +               stack_reg_info[stack_regno].dies_at_store = 0;
  23080. +               stack_reg_info[stack_regno].store_insn = NULL;
  23081. +               stack_reg_info[stack_regno].last_use = NULL;
  23082. +               stack_reg_info[stack_regno].num_non_dead_store = 0;
  23083. +             }
  23084. +             }
  23085. +         }
  23086. +         }
  23087. +     }
  23088. +     }
  23089. + }
  23090. + /*
  23091. +     Change
  23092. +             fst   mem1
  23093. +             fstp  mem2
  23094. +     to
  23095. +            fstp  mem1
  23096. +            mov   mem1,mem2
  23097. +     regno is the number of the stack register being stored.  
  23098. + */
  23099. + opt_consec_stores (regno)
  23100. +      int regno;
  23101. + {
  23102. +   rtx insn, note;
  23103. +   if (stack_reg_info[regno].store_insn
  23104. +       && stack_reg_info[regno].dies_at_store
  23105. +       && stack_reg_info[regno].num_non_dead_store != 0
  23106. +       && stack_reg_info[regno].non_dead_store[0] ==
  23107. +       PREV_INSN (stack_reg_info[regno].store_insn))
  23108. +     {
  23109. +       insn = stack_reg_info[regno].store_insn;
  23110. +       SET_SRC (PATTERN (insn)) 
  23111. +     = copy_rtx (SET_DEST (PATTERN (stack_reg_info[regno].non_dead_store[0])));
  23112. +       if (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == PRE_DEC
  23113. +       || GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == PRE_INC)
  23114. +     {
  23115. +       XEXP (SET_SRC (PATTERN (insn)), 0) =
  23116. +         XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0);
  23117. +     }
  23118. +       INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
  23119. +       note = find_regno_note (insn, REG_DEAD, regno);
  23120. +       remove_note (insn, note);
  23121. +       if (!find_regno_note (stack_reg_info[regno].non_dead_store[0], REG_DEAD, regno))
  23122. +     {
  23123. +       REG_NOTES (stack_reg_info[regno].non_dead_store[0])
  23124. +         = gen_rtx (EXPR_LIST, REG_DEAD, regno_reg_rtx[regno],
  23125. +                REG_NOTES (stack_reg_info[regno].non_dead_store[0]));
  23126. +     }
  23127. +     }
  23128. + }
  23129. + /*
  23130. +   If the register being compared is the result of a computation in
  23131. +   this block, and the second comparison operand is not so, and it is
  23132. +   being compared for equality.  
  23133. +     offload and reload it before the compare
  23134. +   The reason for this is that the stack registers are 80bit precision
  23135. +   and hence the comparison may fail due to precision.  
  23136. + */
  23137. + static void
  23138. + offload_if_necessary (insn, blocknum)
  23139. +      rtx insn;
  23140. +      int blocknum;
  23141. + {
  23142. +   rtx cmp_part, new_insn, last_set_insn, assign_stack_local ();
  23143. +   int regno;
  23144. +   if (GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
  23145. +     {
  23146. +       cmp_part = XVECEXP (PATTERN (insn), 0, 0);
  23147. +       last_set_insn = NULL;
  23148. +       if (SET_DEST (cmp_part) == cc0_rtx
  23149. +       && GET_CODE (SET_SRC (cmp_part)) == COMPARE
  23150. +       && GET_MODE (SET_SRC (cmp_part)) == CCmode)
  23151. +     {
  23152. +       if (GET_CODE (XEXP (SET_SRC (cmp_part), 0)) == REG
  23153. +           && GET_MODE (XEXP (SET_SRC (cmp_part), 0)) == DFmode
  23154. +           && GET_CODE (XEXP (SET_SRC (cmp_part), 1)) != REG
  23155. +           && !reg_last_loaded (blocknum, PREV_INSN (insn),
  23156. +                REGNO (XEXP (SET_SRC (cmp_part), 0)), &last_set_insn)
  23157. +           && last_set_insn
  23158. +           && tests_equality (NEXT_INSN (insn)))
  23159. +         {
  23160. +           regno = REGNO (XEXP (SET_SRC (cmp_part), 0));
  23161. +           if (reg_temp_slot[regno] == NULL)
  23162. +         {
  23163. +           reg_temp_slot[regno] 
  23164. +             = assign_stack_local (GET_MODE (XEXP (SET_SRC (cmp_part), 0)),
  23165. +             GET_MODE_SIZE (GET_MODE (XEXP (SET_SRC (cmp_part), 0))),
  23166. +                     -1);
  23167. +         }
  23168. +           MEM_VOLATILE_P (reg_temp_slot[regno]) = 1;
  23169. +           new_insn 
  23170. +         = emit_insn_before (
  23171. +                    gen_rtx (SET, 0,
  23172. +             reg_temp_slot[regno], XEXP (SET_SRC (cmp_part), 0)),
  23173. +                    insn);
  23174. +           if (basic_block_head[blocknum] == insn)
  23175. +         {
  23176. +           basic_block_head[blocknum] = new_insn;
  23177. +         }
  23178. +           REG_NOTES (new_insn) 
  23179. +         = gen_rtx (EXPR_LIST, REG_DEAD,
  23180. +              XEXP (SET_SRC (cmp_part), 0),
  23181. +              REG_NOTES (new_insn));
  23182. +           reg_n_deaths[regno]++;
  23183. +           emit_insn_before (
  23184. +                  gen_rtx (SET, 0,
  23185. +             XEXP (SET_SRC (cmp_part), 0), reg_temp_slot[regno]),
  23186. +                  insn);
  23187. +         }
  23188. +     }
  23189. +     }
  23190. + }
  23191. + /*
  23192. +   Return 1 if the insn which is a jump insn tests for equality or
  23193. +   inequality
  23194. +   else return 0
  23195. + */
  23196. + static int
  23197. + tests_equality (insn)
  23198. +      rtx insn;
  23199. + {
  23200. +   if (GET_CODE (insn) == JUMP_INSN &&
  23201. +       GET_CODE (PATTERN (insn)) == SET &&
  23202. +       SET_DEST (PATTERN (insn)) == pc_rtx &&
  23203. +       GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE &&
  23204. +       (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == NE ||
  23205. +        GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == EQ))
  23206. +     {
  23207. +       return (1);
  23208. +     }
  23209. +   return (0);
  23210. + }
  23211. + /*
  23212. +    Search backward in block# blocknum, beginning at insn for a set of
  23213. +    reg# regno. 
  23214. +    if found
  23215. +      set *last_set_insn to that set
  23216. +      if the source that sets regno is one of the desired sources
  23217. +      (see below) return 1
  23218. +      else return 0
  23219. +    else return 0
  23220. + */
  23221. + static int
  23222. + reg_last_loaded (blocknum, insn, regno, last_set_insn)
  23223. +      int blocknum, regno;
  23224. +      rtx insn, *last_set_insn;
  23225. + {
  23226. +   rtx last_set;
  23227. +   int found, i;
  23228. +   last_set = insn;
  23229. +   found = 0;
  23230. +   while (!found && last_set != PREV_INSN (basic_block_head[blocknum]))
  23231. +     {
  23232. +       if (GET_CODE (last_set) == INSN)
  23233. +     {
  23234. +       if (GET_CODE (PATTERN (last_set)) == PARALLEL)
  23235. +         {
  23236. +           for (i = 0; i < XVECLEN (PATTERN (last_set), 0); i++)
  23237. +         {
  23238. +           if (GET_CODE (XVECEXP (PATTERN (last_set), 0, i)) == SET)
  23239. +             {
  23240. +               if (GET_CODE (SET_DEST (XVECEXP (PATTERN (last_set), 0, i))) == REG &&
  23241. +               REGNO (SET_DEST (XVECEXP (PATTERN (last_set), 0, i))) == regno)
  23242. +             {
  23243. +               *last_set_insn = last_set;
  23244. +               return (0);
  23245. +             }
  23246. +             }
  23247. +           else if (GET_CODE (XVECEXP (PATTERN (last_set), 0, i)) == CLOBBER)
  23248. +             {
  23249. +               if (GET_CODE (SET_DEST (XVECEXP (PATTERN (last_set), 0, i))) == REG &&
  23250. +               REGNO (SET_DEST (XVECEXP (PATTERN (last_set), 0, i))) == regno)
  23251. +             {
  23252. +               *last_set_insn = last_set;
  23253. +               return (0);
  23254. +             }
  23255. +             }
  23256. +           else
  23257. +             {
  23258. +               return (0);
  23259. +             }
  23260. +         }
  23261. +         }
  23262. +       if ((GET_CODE (PATTERN (last_set)) == SET ||
  23263. +            GET_CODE (PATTERN (last_set)) == CLOBBER) &&
  23264. +           GET_CODE (SET_DEST (PATTERN (last_set))) == REG &&
  23265. +           REGNO (SET_DEST (PATTERN (last_set))) == regno)
  23266. +         {
  23267. +           if (GET_CODE (PATTERN (last_set)) == CLOBBER)
  23268. +         {
  23269. +           *last_set_insn = last_set;
  23270. +           return (0);
  23271. +         }
  23272. +           if (GET_CODE (SET_SRC (PATTERN (last_set))) != MEM
  23273. +           && GET_CODE (SET_SRC (PATTERN (last_set))) != CONST_DOUBLE
  23274. +           && GET_CODE (SET_SRC (PATTERN (last_set))) != REG
  23275. +           && GET_CODE (SET_SRC (PATTERN (last_set))) != SUBREG
  23276. +           && GET_CODE (SET_SRC (PATTERN (last_set))) != FLOAT
  23277. +           && GET_CODE (SET_SRC (PATTERN (last_set))) != FLOAT_EXTEND)
  23278. +         {
  23279. +           *last_set_insn = last_set;
  23280. +           return (0);
  23281. +         }
  23282. +           else
  23283. +         {
  23284. +           *last_set_insn = last_set;
  23285. +           if (GET_CODE (SET_SRC (PATTERN (last_set))) == REG &&
  23286. +               REGNO (SET_SRC (PATTERN (last_set))) < FIRST_PSEUDO_REGISTER)
  23287. +             return (0);
  23288. +           return (1);
  23289. +         }
  23290. +         }
  23291. +     }
  23292. +       if (!found)
  23293. +     {
  23294. +       last_set = PREV_INSN (last_set);
  23295. +     }
  23296. +     }
  23297. +   return (0);
  23298. + }
  23299. + /*
  23300. +   insn loads a stack reg from memory and later on in the block
  23301. +   at stack_reg_info[REGNO(SET_DEST(PATTERN(insn)))].store_insn
  23302. +   that stack reg is stored into memory and marked as dead.  Also
  23303. +   no insn between these two insns sets that stack reg. 
  23304. +   This procedure changes the store from the register stack to
  23305. +   a store from the regular stack - which is faster.  
  23306. + */
  23307. + static void
  23308. + replace_with_stack_slot (insn, block_num, num_calls)
  23309. +      rtx insn;
  23310. +      int block_num, num_calls;
  23311. + {
  23312. +   rtx note, stack_slot, store_insn, new_insn;
  23313. +   rtx notes_to_move, assign_stack_local ();
  23314. +   int i, regno, mem_possibly_changed;
  23315. +   char *storage;
  23316. +   notes_to_move = NULL;
  23317. +   regno = REGNO (SET_DEST (PATTERN (insn)));
  23318. +   store_insn = stack_reg_info[regno].store_insn;
  23319. +   storage = (char *) obstack_alloc (&momentary_obstack, 0);
  23320. +   /* Check if the memory being loaded into the stack register may
  23321. +      possibly change between insn and store_insn.  
  23322. +   */
  23323. +   mem_possibly_changed 
  23324. +     = (GET_CODE (SET_SRC (PATTERN (insn))) == CONST_DOUBLE) ? 0 :
  23325. +       addr_or_val_changed (SET_SRC (PATTERN (insn)), insn, store_insn);
  23326. +   obstack_free (&momentary_obstack, storage);
  23327. +   if (stack_reg_dump_file)
  23328. +     {
  23329. +       fprintf (stack_reg_dump_file,
  23330. +            "Offload stack reg%d used only within basic block insn %d store_insn %d\n",
  23331. +        regno, INSN_UID (insn), INSN_UID (stack_reg_info[regno].store_insn));
  23332. +       if (stack_reg_info[regno].last_use != NULL)
  23333. +     {
  23334. +       fprintf (stack_reg_dump_file,
  23335. +            " reg used at insn %d\n",
  23336. +            INSN_UID (stack_reg_info[regno].last_use));
  23337. +     }
  23338. +     }
  23339. +   if (reg_temp_slot[regno] == NULL && mem_possibly_changed)
  23340. +     { /* Must allocate a stack slot */
  23341. + #ifdef SPARE_REGS
  23342. +       if (max_reg_num () < max_regno)
  23343. +         {
  23344. +           if (GET_MODE (SET_DEST (PATTERN (insn))) == SFmode)
  23345. +             reg_temp_slot[regno] = gen_reg_rtx (SImode);
  23346. +           else
  23347. +             reg_temp_slot[regno] 
  23348. +           = assign_stack_local (GET_MODE (SET_DEST (PATTERN (insn))),
  23349. +            GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (insn)))),
  23350. +                 -1);
  23351. +         }
  23352. +       else
  23353. + #endif
  23354. +         reg_temp_slot[regno] 
  23355. +       = assign_stack_local (GET_MODE (SET_DEST (PATTERN (insn))),
  23356. +                GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (insn)))),
  23357. +                 -1);
  23358. +     }
  23359. +   if (mem_possibly_changed)
  23360. +     /* Use the stack slot */
  23361. +     stack_slot = reg_temp_slot[regno];
  23362. +   else
  23363. +     /* The memory slot from which the stack register was loaded can be used */
  23364. +     stack_slot = SET_SRC (PATTERN (insn));
  23365. +   if (stack_reg_info[regno].last_use == NULL)
  23366. +     { /* The stack register was not used between the load and store */
  23367. +       if (mem_possibly_changed)
  23368. +     {
  23369. +       SET_DEST (PATTERN (insn)) = stack_slot;
  23370. +       if (GET_CODE (stack_slot) == REG)
  23371. +         {
  23372. +               if (GET_CODE (SET_SRC (PATTERN (insn)))
  23373. +                   == CONST_DOUBLE)
  23374. +                 {
  23375. +                   SET_SRC (PATTERN (insn)) = 
  23376. +                     gen_rtx (CONST_INT, 0, CONST_DOUBLE_HIGH (SET_SRC (PATTERN (insn))));
  23377. +                 }
  23378. +               else
  23379. +                 {
  23380. +               PUT_MODE (SET_SRC (PATTERN (insn)), GET_MODE (stack_slot));
  23381. +             }
  23382. +         }
  23383. +       INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
  23384. +     }
  23385. +       else
  23386. +     {
  23387. +       PUT_CODE (insn, NOTE);
  23388. +       NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
  23389. +       NOTE_SOURCE_FILE (insn) = 0;
  23390. +       notes_to_move = REG_NOTES (insn);
  23391. +     }
  23392. +     }
  23393. +   else
  23394. +     { /* The stack register was also used in some computation */
  23395. +       if (mem_possibly_changed)
  23396. +     {
  23397. +       new_insn 
  23398. +         = emit_insn_after (
  23399. +       gen_rtx (SET, 0, stack_slot, copy_rtx (SET_SRC (PATTERN (insn)))),
  23400. +                   insn);
  23401. +       if (GET_CODE (stack_slot) == REG)
  23402. +         {
  23403. +           PUT_MODE (SET_SRC (PATTERN (new_insn)), GET_MODE (stack_slot));
  23404. +         }
  23405. +       INSN_CODE (new_insn) = recog (PATTERN (new_insn), new_insn, 0);
  23406. +     }
  23407. +     }
  23408. +   SET_SRC (PATTERN (store_insn)) = stack_slot;
  23409. +   if (GET_CODE (stack_slot) == REG )
  23410. +     {
  23411. +       reg_n_refs[REGNO (stack_slot)]++;
  23412. +       reg_n_sets[REGNO (stack_slot)]++;
  23413. +       reg_n_calls_crossed[REGNO (stack_slot)] = num_calls;
  23414. +       reg_n_deaths[REGNO (stack_slot)]++;
  23415. +       if (reg_basic_block[REGNO (stack_slot)] != -1)
  23416. +         {
  23417. +           reg_basic_block[REGNO (stack_slot)] = REG_BLOCK_GLOBAL;
  23418. +         }
  23419. +       else
  23420. +         {
  23421. +           reg_basic_block[REGNO (stack_slot)] = block_num;
  23422. +         }
  23423. +       PUT_MODE (SET_DEST (PATTERN (store_insn)), GET_MODE (stack_slot));
  23424. +       REG_NOTES (store_insn) = 
  23425. +         gen_rtx (EXPR_LIST, REG_DEAD, stack_slot, REG_NOTES (store_insn));
  23426. +     }
  23427. +   INSN_CODE (store_insn) = recog (PATTERN (store_insn), store_insn, 0);
  23428. +   note = find_regno_note (store_insn, REG_DEAD, regno);
  23429. +   remove_note (store_insn, note);
  23430. +   if (notes_to_move)
  23431. +     { /* Maintain consistency of REG NOTE information */
  23432. +       rtx link, prev_link;
  23433. +       prev_link = REG_NOTES (store_insn);
  23434. +       for (link = REG_NOTES (store_insn); link; link = XEXP (link, 1))
  23435. +     {
  23436. +       prev_link = link;
  23437. +     }
  23438. +       if (prev_link)
  23439. +     {
  23440. +       XEXP (prev_link, 1) = notes_to_move;
  23441. +     }
  23442. +       else
  23443. +     {
  23444. +       REG_NOTES (store_insn) = notes_to_move;
  23445. +     }
  23446. +     }
  23447. +   if (stack_reg_info[regno].last_use == NULL)
  23448. +     {
  23449. +       reg_n_deaths[regno]--;
  23450. +     }
  23451. +   else if (!find_regno_note (stack_reg_info[regno].last_use, REG_DEAD, regno))
  23452. +     {
  23453. +       REG_NOTES (stack_reg_info[regno].last_use)
  23454. +     = gen_rtx (EXPR_LIST, REG_DEAD, regno_reg_rtx[regno],
  23455. +            REG_NOTES (stack_reg_info[regno].last_use));
  23456. +     }
  23457. +   for (i = 0;
  23458. +        i < (int) stack_reg_info[regno].num_non_dead_store;
  23459. +        i++)
  23460. +     { /* Handle the stores of the stack register that were done
  23461. +          between insn and store_insn.  */
  23462. +       store_insn 
  23463. +     = stack_reg_info[regno].non_dead_store[i];
  23464. +       SET_SRC (PATTERN (store_insn)) = stack_slot;
  23465. +       if (GET_CODE (stack_slot) == REG )
  23466. +         {
  23467. +           reg_n_refs[REGNO (stack_slot)]++;
  23468. +           PUT_MODE (SET_DEST (PATTERN (store_insn)), GET_MODE (stack_slot));
  23469. +         }
  23470. +       INSN_CODE (store_insn) = recog (PATTERN (store_insn), store_insn, 0);
  23471. +     }
  23472. +   stack_reg_info[regno].store_insn = NULL;
  23473. +   stack_reg_info[regno].last_use = NULL;
  23474. +   stack_reg_info[regno].num_non_dead_store = 0;
  23475. +   stack_reg_info[regno].dies_at_store = 0;
  23476. + }
  23477. + /*
  23478. +   GET_CODE(mem) is MEM
  23479. +   we are interested in the insns between start_insn and stop_insn
  23480. +   (non inclusive)
  23481. +   return 1 if the address of mem or the contents of mem may POSSIBLY
  23482. +   be changed in this interval
  23483. +   return 0 otherwise
  23484. +     by address of mem changing we mean that mem contains a base and/or
  23485. +     index register and some insn in the interval sets the register.
  23486. + */
  23487. + static int
  23488. + addr_or_val_changed (mem, start_insn, stop_insn)
  23489. +      rtx mem, start_insn, stop_insn;
  23490. + {
  23491. +   rtx insn;
  23492. +   struct regs_mentioned *a_reg_mentioned;
  23493. +   char * storage;
  23494. +   if (MEM_VOLATILE_P (mem))
  23495. +     {
  23496. +       return (1);
  23497. +     }
  23498. +   /*
  23499. +   if (RTX_UNCHANGING_P (mem))
  23500. +     {
  23501. +       return (0);
  23502. +     } */
  23503. +   reg_mentioned_header = NULL;
  23504. +   storage = (char *) obstack_alloc (&momentary_obstack, 0);
  23505. +   find_regs_mentioned (mem);
  23506. +   for (insn = NEXT_INSN (start_insn); insn != stop_insn; insn = NEXT_INSN (insn))
  23507. +     {
  23508. +       if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == CODE_LABEL)
  23509. +     {
  23510. +       return (1);
  23511. +     }
  23512. +       if (GET_CODE (insn) == INSN)
  23513. +     {
  23514. +       if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == CLOBBER)
  23515. +         {
  23516. +           if (GET_CODE (SET_DEST (PATTERN (insn))) == MEM)
  23517. +         {
  23518. +           if (true_dependence (mem, SET_DEST (PATTERN (insn))))
  23519. +             {
  23520. +               obstack_free (&momentary_obstack, storage);
  23521. +               return (1);
  23522. +             }
  23523. +         }
  23524. +           else if (GET_CODE (SET_DEST (PATTERN (insn))) == REG)
  23525. +         {
  23526. +           for (a_reg_mentioned = reg_mentioned_header;
  23527. +                a_reg_mentioned != NULL;
  23528. +                a_reg_mentioned = a_reg_mentioned->next)
  23529. +             {
  23530. +               if (reg_overlap_mentioned_p (SET_DEST (PATTERN (insn)),
  23531. +                            a_reg_mentioned->reg)
  23532. +             )
  23533. +             {
  23534. +                     obstack_free (&momentary_obstack, storage);
  23535. +               return (1);
  23536. +             }
  23537. +             }
  23538. +         }
  23539. +           else
  23540. +         {
  23541. +           obstack_free (&momentary_obstack, storage);
  23542. +           return (1);
  23543. +         }
  23544. +         }
  23545. +       else
  23546. +         {
  23547. +           obstack_free (&momentary_obstack, storage);
  23548. +           return (1);
  23549. +         }
  23550. +     }
  23551. +     }
  23552. +   obstack_free (&momentary_obstack, storage);
  23553. +   return (0);
  23554. + }
  23555. + /* Build a linked list of (struct regs_mentioned) describing the
  23556. +    registers used in the pattern pat.  
  23557. + */
  23558. + static void
  23559. + find_regs_mentioned (pat)
  23560. +      rtx pat;
  23561. + {
  23562. +   register char *fmt;
  23563. +   register int i;
  23564. +   register enum rtx_code code;
  23565. +   struct regs_mentioned *one_reg;
  23566. +   code = GET_CODE (pat);
  23567. +   switch (code)
  23568. +     {
  23569. +     case REG:
  23570. +       one_reg = (struct regs_mentioned *)
  23571. +     obstack_alloc (&momentary_obstack, sizeof (struct regs_mentioned));
  23572. +       one_reg->reg = pat;
  23573. +       one_reg->next = reg_mentioned_header;
  23574. +       reg_mentioned_header = one_reg;
  23575. +       return;
  23576. +       /* These codes have no constituent expressions
  23577. +      and are unique.  */
  23578. +     case SCRATCH:
  23579. +     case CC0:
  23580. +     case PC:
  23581. +     case QUEUED:
  23582. +     case CONST_INT:
  23583. +     case CONST_DOUBLE:
  23584. +     case SYMBOL_REF:
  23585. +     case CODE_LABEL:
  23586. +       return;
  23587. +     }
  23588. +   fmt = GET_RTX_FORMAT (code);
  23589. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  23590. +     {
  23591. +       if (fmt[i] == 'E')
  23592. +     {
  23593. +       register int j;
  23594. +       for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
  23595. +         find_regs_mentioned (XVECEXP (pat, i, j));
  23596. +     }
  23597. +       else if (fmt[i] == 'e')
  23598. +     find_regs_mentioned (XEXP (pat, i));
  23599. +     }
  23600. + }
  23601. + /*
  23602. +   if insn stores a stack register into memory
  23603. +     set *regno to the register# stored
  23604. +     if the stack register is marked dead at the store
  23605. +       return 1
  23606. +     else
  23607. +       return 0
  23608. + */
  23609. + static int
  23610. + stack_reg_dies_at_store (insn, regno)
  23611. +      rtx insn;
  23612. +      int *regno;
  23613. + {
  23614. +   if (GET_CODE (SET_DEST (PATTERN (insn))) == MEM
  23615. +       && GET_CODE (SET_SRC (PATTERN (insn))) == REG
  23616. +       && IS_STACK_MODE (GET_MODE (SET_SRC (PATTERN (insn))))
  23617. +     )
  23618. +     {
  23619. +       *regno = REGNO (SET_SRC (PATTERN (insn)));
  23620. +       return ((int) find_regno_note (insn, REG_DEAD, *regno));
  23621. +     }
  23622. +   return (0);
  23623. + }
  23624. + /*
  23625. +   Record relevant information on each stack register that is mentioned
  23626. +   in pat which is a subexpression of insn.  
  23627. + */
  23628. + static void
  23629. + mark_stack_regs_mentioned (pat, insn)
  23630. +      rtx pat, insn;
  23631. + {
  23632. +   register char *fmt;
  23633. +   register int i;
  23634. +   register enum rtx_code code;
  23635. +   code = GET_CODE (pat);
  23636. +   switch (code)
  23637. +     {
  23638. +     case REG:
  23639. +       if (IS_STACK_MODE (GET_MODE (pat)))
  23640. +     {
  23641. +       if (stack_reg_info[REGNO (pat)].last_use == NULL)
  23642. +         {
  23643. +           stack_reg_info[REGNO (pat)].last_use = insn;
  23644. +         }
  23645. +     }
  23646. +       return;
  23647. +       /* These codes have no constituent expressions
  23648. +      and are unique.  */
  23649. +     case SCRATCH:
  23650. +     case CC0:
  23651. +     case PC:
  23652. +     case QUEUED:
  23653. +     case CONST_INT:
  23654. +     case CONST_DOUBLE:
  23655. +     case SYMBOL_REF:
  23656. +     case CODE_LABEL:
  23657. +       return;
  23658. +     }
  23659. +   fmt = GET_RTX_FORMAT (code);
  23660. +   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  23661. +     {
  23662. +       if (fmt[i] == 'E')
  23663. +     {
  23664. +       register int j;
  23665. +       for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
  23666. +         mark_stack_regs_mentioned (XVECEXP (pat, i, j), insn);
  23667. +     }
  23668. +       else if (fmt[i] == 'e')
  23669. +     mark_stack_regs_mentioned (XEXP (pat, i), insn);
  23670. +     }
  23671. + }
  23672. + /*
  23673. +    Stack mode registers that are set in one basic block and only
  23674. +    loaded to or stored from in successor blocks are replaced with
  23675. +    stack slots in the successor blocks. 
  23676. + */
  23677. + static void
  23678. + func_stack_reg_to_stack_slot ()
  23679. + {
  23680. +   rtx head, tail, target;
  23681. +   register regset tem;
  23682. +   int i, j, found, target_blocknum, regno, successful_visit, reg_defined_elsewhere,
  23683. +     reg_set_or_stored, cmprd, only_cmp;
  23684. +   char *storage;
  23685. + #ifdef SPARE_REGS
  23686. +    int max_regno = max_reg_num ();
  23687. + #endif
  23688. +   storage = (char *) obstack_alloc (&momentary_obstack, 0);
  23689. +   basic_block_maybe_live_at_end = (regset *) alloca (n_basic_blocks * sizeof (regset));
  23690. +   tem = (regset) obstack_alloc (&momentary_obstack, n_basic_blocks * regset_bytes);
  23691. +   bzero (tem, n_basic_blocks * regset_bytes);
  23692. +   init_regset_vector (basic_block_maybe_live_at_end, tem, n_basic_blocks, regset_bytes);
  23693. +   jump_target_block = (int *) alloca (n_basic_blocks * sizeof (int));
  23694. +   fall_thru_block = (int *) alloca (n_basic_blocks * sizeof (int));
  23695. +   blocks_visited = (char *) alloca (n_basic_blocks * sizeof (char));
  23696. +   death_blocks = (rtx *) alloca (n_basic_blocks * sizeof (rtx));
  23697. +   blocks_defined = (char *) alloca (n_basic_blocks * sizeof (char));
  23698. +   cmprd = 0;
  23699. +   only_cmp = 1;
  23700. +   if (stack_reg_dump_file)
  23701. +     {
  23702. +       fprintf (stack_reg_dump_file,
  23703. +            "Offload stack regs:\n\n");
  23704. +     }
  23705. +   /* Find block successors */
  23706. +   for (i = 0; i < n_basic_blocks; i++)
  23707. +     {
  23708. +       jump_target_block[i] = -1;
  23709. +       fall_thru_block[i] = -1;
  23710. +       head = basic_block_head[i];
  23711. +       tail = basic_block_end[i];
  23712. +       if (GET_CODE (tail) == JUMP_INSN)
  23713. +     {
  23714. +       target = JUMP_LABEL (tail);
  23715. +       if (target == NULL)
  23716. +         {
  23717. +           return;
  23718. +         }
  23719. +       /* target is the head of the basic block jumped to
  23720. +              find which block it is */
  23721. +       target_blocknum = 0;
  23722. +       found = 0;
  23723. +       while (target_blocknum < n_basic_blocks && !found)
  23724. +         {
  23725. +           if (basic_block_head[target_blocknum] == target)
  23726. +         {
  23727. +           found = 1;
  23728. +         }
  23729. +           else
  23730. +         {
  23731. +           target_blocknum++;
  23732. +         }
  23733. +         }
  23734. +       if (!found)
  23735. +         {
  23736. +           return;
  23737. +         }
  23738. +       jump_target_block[i] = target_blocknum;
  23739. +       for (j = 0; j < regset_size; j++)
  23740. +         basic_block_maybe_live_at_end[i][j]
  23741. +           |= basic_block_live_at_start[target_blocknum][j];
  23742. +     }
  23743. +       if (!simplejump_p (tail))
  23744. +     {
  23745. +       if (i < n_basic_blocks - 1)
  23746. +         {
  23747. +           fall_thru_block[i] = i + 1;
  23748. +           for (j = 0; j < regset_size; j++)
  23749. +         basic_block_maybe_live_at_end[i][j]
  23750. +           |= basic_block_live_at_start[i + 1][j];
  23751. +         }
  23752. +     }
  23753. +     }
  23754. +   if (stack_reg_dump_file)
  23755. +     my_dump_block_info ();
  23756. +   /* Do inter block optimizations */
  23757. +   for (i = 0; i < n_basic_blocks; i++)
  23758. +     {
  23759. +       for (regno = FIRST_PSEUDO_REGISTER; regno < max_regno; regno++)
  23760. +     {
  23761. +       register int offset = regno / REGSET_ELT_BITS;
  23762. +       register int bit = 1 << (regno % REGSET_ELT_BITS);
  23763. +       if (stack_reg_dump_file
  23764. +           && IS_STACK_MODE (GET_MODE (regno_reg_rtx[regno]))
  23765. +           && (basic_block_maybe_live_at_end[i][offset] & bit)
  23766. +           && !(basic_block_live_at_start[i][offset] & bit)
  23767. +         )
  23768. +         {
  23769. +           fprintf (stack_reg_dump_file,
  23770. +                "\nstack reg%d in block %d  d_a_p %d\n",
  23771. +                regno, i,
  23772. +                reg_dead_at_pred (offset, bit, i));
  23773. +         }
  23774. +       if ((basic_block_maybe_live_at_end[i][offset] & bit)
  23775. +           && reg_dead_at_pred (offset, bit, i)
  23776. +           && !(basic_block_live_at_start[i][offset] & bit)
  23777. +           && IS_STACK_MODE (GET_MODE (regno_reg_rtx[regno])))
  23778. +         {
  23779. +           /* A stack register that is live at the exit of the
  23780. +                  block and not live on entry */
  23781. +           if (stack_reg_dump_file)
  23782. +         {
  23783. +           fprintf (stack_reg_dump_file,
  23784. +           "\nstack reg%d in block %d live at end but not at start\n",
  23785. +                regno, i);
  23786. +         }
  23787. +           bzero (blocks_visited, n_basic_blocks * sizeof (char));
  23788. +           bzero (death_blocks, n_basic_blocks * sizeof (rtx));
  23789. +           num_visits = 0;
  23790. +           successful_visit = visit_till_dies (regno, i);
  23791. +           if (stack_reg_dump_file)
  23792. +         {
  23793. +           fprintf (stack_reg_dump_file, " blocks visited : ");
  23794. +           for (j = 0; j < n_basic_blocks; j++)
  23795. +             {
  23796. +               if (blocks_visited[j])
  23797. +             {
  23798. +               fprintf (stack_reg_dump_file, "%d ", j);
  23799. +             }
  23800. +             }
  23801. +           fprintf (stack_reg_dump_file, "\n");
  23802. +         }
  23803. +           successful_visit = 
  23804. +             successful_visit && death_blocks_ok (regno);
  23805. +           bzero (blocks_defined, n_basic_blocks * sizeof (char));
  23806. +           blocks_defined[i] = 1;
  23807. +           reg_defined_elsewhere = reg_def_in_unvisited (offset, bit, i);
  23808. +           reg_set_or_stored 
  23809. +         = reg_only_set_or_stored (regno, i, &cmprd, &only_cmp);
  23810. +           if (successful_visit
  23811. +           && !reg_defined_elsewhere
  23812. +           && reg_set_or_stored)
  23813. +         {  /* This reg was never used in any computation after
  23814. +                       this set until it's death - so don't keep
  23815. +                       it in stack reg after block i.  Allocate a temp slot
  23816. +                       for it and store it there at the end of block i.  
  23817. +                       In all visited blocks replace regno with this
  23818. +                       temp slot.  */
  23819. +           if (stack_reg_dump_file)
  23820. +             {
  23821. +               fprintf (stack_reg_dump_file,
  23822. +               " only loaded or stored in all visited blocks\n");
  23823. +             }
  23824. +           if (store_into_temp (regno, i))
  23825. +             {
  23826. +               if (stack_reg_dump_file)
  23827. +             {
  23828. +               fprintf (stack_reg_dump_file,
  23829. +               " replaced by temp slot in all blocks visited\n");
  23830. +             }
  23831. +               replace_with_temp_slot (regno, i);
  23832. +             }
  23833. +         }
  23834. +           else if (successful_visit && cmprd)
  23835. +         {
  23836. +           /* In each block where regno is defined by a computation
  23837. +                      store it and reload it to avoid precision problems
  23838. +                      in comparison */
  23839. +           offload_reg (regno);
  23840. +         }
  23841. +           if (stack_reg_dump_file)
  23842. +         {
  23843. +           fprintf (stack_reg_dump_file,
  23844. +                "  successful visit %d  cmprd %d\n", successful_visit, cmprd);
  23845. +         }
  23846. +         }
  23847. +     }
  23848. +     }
  23849. +   obstack_free (&momentary_obstack, storage);
  23850. + }
  23851. + /*
  23852. +   The blocks where the stack reg dies on the visit have been
  23853. +   marked by death_blocks[block_num] being set to the NEXT_INSN
  23854. +   of the insn where it dies in the block.  
  23855. +   For each of these blocks either the register must not be redefined
  23856. +   in the block or none of the successors of the block have been
  23857. +   visited.  
  23858. + */
  23859. + static int
  23860. + death_blocks_ok (regno)
  23861. +      int regno;
  23862. + {
  23863. +   int i, successor_visited;
  23864. +   for (i = 0; i < n_basic_blocks; i++)
  23865. +     {
  23866. +       if (death_blocks[i])
  23867. +     {
  23868. +       successor_visited = 0;
  23869. +       if (fall_thru_block[i] != -1
  23870. +           && blocks_visited[fall_thru_block[i]])
  23871. +         {
  23872. +           successor_visited = 1;
  23873. +         }
  23874. +       if (successor_visited == 0 && jump_target_block[i] != -1
  23875. +           && blocks_visited[jump_target_block[i]])
  23876. +         {
  23877. +           successor_visited = 1;
  23878. +         }
  23879. +       if (successor_visited == 0)
  23880. +         {
  23881. +           continue;
  23882. +         }
  23883. +       else if (reg_set_between_p (regno_reg_rtx[regno],
  23884. +                       PREV_INSN (death_blocks[i]),
  23885. +                       NEXT_INSN (basic_block_end[i])))
  23886. +         {
  23887. +           return (0);
  23888. +         }
  23889. +     }
  23890. +     }
  23891. +   return (1);
  23892. + }
  23893. + /*
  23894. +   Like offload_if_necessary but for stack registers used in equality
  23895. +   comparisons in one basic block and computed in another.  The offload
  23896. +   and reload are done at the place of computation.  
  23897. + */
  23898. + static void
  23899. + offload_reg (regno)
  23900. +      int regno;
  23901. + {
  23902. +   int block, reg_loaded;
  23903. +   rtx last_set_insn, new_insn;
  23904. +   if (stack_reg_dump_file)
  23905. +     {
  23906. +       fprintf (stack_reg_dump_file,
  23907. +            "offload compared reg %d\n", regno);
  23908. +     }
  23909. +   for (block = 0; block < n_basic_blocks; block++)
  23910. +     {
  23911. +       if (blocks_defined[block])
  23912. +     {
  23913. +       if (stack_reg_dump_file)
  23914. +         {
  23915. +           fprintf (stack_reg_dump_file,
  23916. +                " defined in block %d\n", block);
  23917. +         }
  23918. +       last_set_insn = NULL;
  23919. +       reg_loaded 
  23920. +         = reg_last_loaded (block, basic_block_end[block], regno, &last_set_insn);
  23921. +       if (stack_reg_dump_file)
  23922. +         {
  23923. +           fprintf (stack_reg_dump_file,
  23924. +                "  reg loaded %d ", reg_loaded);
  23925. +           if (last_set_insn)
  23926. +         fprintf (stack_reg_dump_file,
  23927. +              " last_set_insn %d", INSN_UID (last_set_insn));
  23928. +           fprintf (stack_reg_dump_file, "\n");
  23929. +         }
  23930. +       if (reg_loaded == 0 && last_set_insn)
  23931. +         {
  23932. +           if (stack_reg_dump_file)
  23933. +         {
  23934. +           fprintf (stack_reg_dump_file,
  23935. +                "   actually offloading\n");
  23936. +         }
  23937. +           if (reg_temp_slot[regno] == NULL)
  23938. +         {
  23939. +           reg_temp_slot[regno] 
  23940. +             = assign_stack_local (GET_MODE (regno_reg_rtx[regno]),
  23941. +                 GET_MODE_SIZE (GET_MODE (regno_reg_rtx[regno])),
  23942. +                     -1);
  23943. +         }
  23944. +           MEM_VOLATILE_P (reg_temp_slot[regno]) = 1;
  23945. +           new_insn 
  23946. +         = emit_insn_before (
  23947. +                    gen_rtx (SET, 0,
  23948. +                 reg_temp_slot[regno], regno_reg_rtx[regno]),
  23949. +                    NEXT_INSN (last_set_insn));
  23950. +           REG_NOTES (new_insn) 
  23951. +             = gen_rtx (EXPR_LIST, REG_DEAD,
  23952. +              regno_reg_rtx[regno],
  23953. +              REG_NOTES (new_insn));
  23954. +           reg_n_deaths[regno]++;
  23955. +           new_insn 
  23956. +         = emit_insn_before (
  23957. +                    gen_rtx (SET, 0,
  23958. +                 regno_reg_rtx[regno], reg_temp_slot[regno]),
  23959. +                    NEXT_INSN (new_insn));
  23960. +           if (basic_block_end[block] == last_set_insn)
  23961. +         {
  23962. +           basic_block_end[block] = new_insn;
  23963. +         }
  23964. +         }
  23965. +     }
  23966. +     }
  23967. + }
  23968. + /*
  23969. +   If the reg given by offset an bit in the live vecotrs is not live
  23970. +   at the end of any blocks that are the predecessors of blocknum
  23971. +   (except blocknum itself)
  23972. +     return 1
  23973. +   else
  23974. +     return 0
  23975. + */
  23976. + static int
  23977. + reg_dead_at_pred (offset, bit, blocknum)
  23978. +      int offset, bit, blocknum;
  23979. + {
  23980. +   rtx head, jump;
  23981. +   int i;
  23982. +   head = basic_block_head[blocknum];
  23983. +   if (GET_CODE (head) == CODE_LABEL)
  23984. +     for (jump = LABEL_REFS (head);
  23985. +      jump != head;
  23986. +      jump = LABEL_NEXTREF (jump))
  23987. +       {
  23988. +     for (i = 0; i < n_basic_blocks; i++)
  23989. +       {
  23990. +         if (basic_block_end[i] == CONTAINING_INSN (jump))
  23991. +           break;
  23992. +       }
  23993. +     if (i == n_basic_blocks)
  23994. +       {
  23995. +         return (0);
  23996. +       }
  23997. +     if (i != blocknum)
  23998. +       {
  23999. +         if (basic_block_maybe_live_at_end[i][offset] & bit)
  24000. +           {
  24001. +         return (0);
  24002. +           }
  24003. +       }
  24004. +       }
  24005. +   if ((blocknum - 1) == -1 ||
  24006. +       simplejump_p (basic_block_end[blocknum - 1]) ||
  24007. +       !(basic_block_maybe_live_at_end[blocknum - 1][offset] & bit))
  24008. +     {
  24009. +       return (1);
  24010. +     }
  24011. +   return (0);
  24012. + }
  24013. + /*
  24014. +   If the definition of the register in some visited block is
  24015. +   done by a block that has not been visited then return 1
  24016. + */
  24017. + static int
  24018. + reg_def_in_unvisited (offset, bit, blocknum)
  24019. +      int offset, bit, blocknum;
  24020. + {
  24021. +   int i, j, ret_val;
  24022. +   rtx head, jump;
  24023. +   ret_val = 0;
  24024. +   for (i = 0; i < n_basic_blocks; i++)
  24025. +     {
  24026. +       if (i != blocknum && blocks_visited[i])
  24027. +     {
  24028. +       head = basic_block_head[i];
  24029. +       if (GET_CODE (head) == CODE_LABEL)
  24030. +         for (jump = LABEL_REFS (head);
  24031. +          jump != head;
  24032. +          jump = LABEL_NEXTREF (jump))
  24033. +           {
  24034. +         for (j = 0; j < n_basic_blocks; j++)
  24035. +           {
  24036. +             if (basic_block_end[j] == CONTAINING_INSN (jump))
  24037. +               break;
  24038. +           }
  24039. +         if (j == n_basic_blocks)
  24040. +           {
  24041. +             ret_val = 1;
  24042. +           }
  24043. +         if (blocks_visited[j] == 0 && j != i)
  24044. +           {
  24045. +             if (basic_block_maybe_live_at_end[j][offset] & bit)
  24046. +               {
  24047. +             blocks_defined[j] = 1;
  24048. +             ret_val = 1;
  24049. +               }
  24050. +           }
  24051. +           }
  24052. +       if ((i - 1) != -1
  24053. +           && !simplejump_p (basic_block_end[i - 1])
  24054. +           && blocks_visited[i - 1] == 0
  24055. +           && basic_block_maybe_live_at_end[i - 1][offset] & bit)
  24056. +         {
  24057. +           blocks_defined[i - 1] = 1;
  24058. +           ret_val = 1;
  24059. +         }
  24060. +     }
  24061. +     }
  24062. +   return (ret_val);
  24063. + }
  24064. + /* regno is never used in any computation from it's set in
  24065. +    source_blocknum until it's death - so don't keep
  24066. +    it in stack reg after source_blocknum.  Allocate a temp slot
  24067. +    for it and store it there at the end of block source_blocknum.
  24068. +    In all visited blocks replace regno with this temp slot. 
  24069. +    In blocks where regno dies the replacement is done
  24070. +    up until the insn in which regno dies.  
  24071. + */
  24072. + static void
  24073. + replace_with_temp_slot (regno, source_blocknum)
  24074. + {
  24075. +   int i, had_call, num_insns;
  24076. +   rtx insn, note;
  24077. +   register int offset = regno / REGSET_ELT_BITS;
  24078. +   register int bit = 1 << (regno % REGSET_ELT_BITS);
  24079. +   register int compl_bit;
  24080. +   compl_bit = ~bit;
  24081. +   for (i = 0; i < n_basic_blocks; i++)
  24082. +     {
  24083. +       if (blocks_visited[i] && i != source_blocknum)
  24084. +     {
  24085. +       basic_block_live_at_start[i][offset] &= compl_bit;
  24086. +       if (!death_blocks[i])
  24087. +         {
  24088. +           basic_block_maybe_live_at_end[i][offset] &= compl_bit;
  24089. +         }
  24090. +       had_call = 0;
  24091. +       num_insns = 0;
  24092. +       for (insn = basic_block_head[i];
  24093. +            insn && insn != death_blocks[i]
  24094. +            && insn != NEXT_INSN (basic_block_end[i]);
  24095. +            insn = NEXT_INSN (insn))
  24096. +         {
  24097. +           num_insns++;
  24098. +           if (GET_CODE (insn) == CALL_INSN)
  24099. +             had_call = 1;
  24100. +           if (GET_CODE (insn) == INSN)
  24101. +         {
  24102. +           init_undo_buf ();
  24103. +           subst_in_insn (insn, PATTERN (insn), regno_reg_rtx[regno],
  24104. +                  reg_temp_slot[regno], 0, 0);
  24105. +           if (GET_CODE (reg_temp_slot[regno]) == REG
  24106. +               && GET_CODE (PATTERN (insn)) == SET)
  24107. +             {
  24108. +                   register int n_offset = 
  24109. +                     REGNO (reg_temp_slot[regno]) / REGSET_ELT_BITS;
  24110. +                   register REGSET_ELT_TYPE n_bit
  24111. +                     = (REGSET_ELT_TYPE) 1 
  24112. +                       << (REGNO (reg_temp_slot[regno]) % REGSET_ELT_BITS);
  24113. +                   basic_block_live_at_start[i][n_offset] |= n_bit;
  24114. +                   reg_basic_block[REGNO (reg_temp_slot[regno])] = REG_BLOCK_GLOBAL;
  24115. +               if (rtx_equal_p (reg_temp_slot[regno], 
  24116. +                                SET_DEST (PATTERN (insn))))
  24117. +                 {
  24118. +                   reg_n_sets[REGNO (reg_temp_slot[regno])]++;
  24119. +                   reg_n_refs[REGNO (reg_temp_slot[regno])]++;
  24120. +                           if (GET_CODE (SET_SRC (PATTERN (insn)))
  24121. +                               == CONST_DOUBLE)
  24122. +                             {
  24123. +                               union
  24124. +                                 {
  24125. +                                   int i[2];
  24126. +                                   double d;
  24127. +                                 }
  24128. +                               u1;
  24129. +                               union
  24130. +                                 {
  24131. +                                   int i;
  24132. +                                   float f;
  24133. +                                 }
  24134. +                               u2;
  24135. +                               u1.i[0] = 
  24136. +                                 CONST_DOUBLE_LOW (SET_SRC (PATTERN (insn)));
  24137. +                               u1.i[1] = 
  24138. +                                 CONST_DOUBLE_HIGH (SET_SRC (PATTERN (insn)));
  24139. +                               u2.f = u1.d;
  24140. +                               SET_SRC (PATTERN (insn)) = 
  24141. +                                 gen_rtx (CONST_INT, 0, u2.i);
  24142. +                             }
  24143. +                           else
  24144. +                             {
  24145. +                       PUT_MODE (SET_SRC (PATTERN (insn)), 
  24146. +                             GET_MODE (reg_temp_slot[regno]));
  24147. +                     }
  24148. +                 }
  24149. +               if (rtx_equal_p (reg_temp_slot[regno], 
  24150. +                                SET_SRC (PATTERN (insn))))
  24151. +                 {
  24152. +                   PUT_MODE (SET_DEST (PATTERN (insn)), 
  24153. +                             GET_MODE (reg_temp_slot[regno]));
  24154. +                   reg_live_length[REGNO (reg_temp_slot[regno])] 
  24155. +                     += num_insns;
  24156. +                   reg_n_refs[REGNO (reg_temp_slot[regno])]++;
  24157. +                   if (had_call)
  24158. +                     {
  24159. +                       reg_n_calls_crossed[REGNO (reg_temp_slot[regno])]++;
  24160. +                     }
  24161. +                 }
  24162. +             }
  24163. +           INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
  24164. +           if ((note = find_regno_note (insn, REG_DEAD, regno)) != NULL)
  24165. +             {
  24166. +               if (GET_CODE (reg_temp_slot[regno]) == REG)
  24167. +                 {
  24168. +                   XEXP (note, 0) = reg_temp_slot[regno];
  24169. +                   reg_n_deaths[REGNO (reg_temp_slot[regno])]++;
  24170. +                 }
  24171. +               else
  24172. +                 remove_note (insn, note);
  24173. +             }
  24174. +         }
  24175. +         }
  24176. +     }
  24177. +     }
  24178. + }
  24179. + /*
  24180. +   If in each block_visited (except source_blocknum) regno is only
  24181. +   set, or used as a source in a store then
  24182. +     return 1
  24183. +   else
  24184. +     return 0
  24185. +   *used_in_cmp is set to 1 if regno is used in a comparison
  24186. +   in a block and it was not last set by a load before that
  24187. +   comparison
  24188. +   *only_cmp is set to 1 if the only other use of regno besides
  24189. +   as a dest or source of a store is in comparison, otherwise it
  24190. +   is set to 0
  24191. + */
  24192. + static int
  24193. + reg_only_set_or_stored (regno, source_blocknum, used_in_cmp, only_cmp)
  24194. +      int regno, source_blocknum, *used_in_cmp, *only_cmp;
  24195. + {
  24196. +   int i, ret_val;
  24197. +   rtx insn, cmp_part, last_set_insn;
  24198. +   ret_val = 1;
  24199. +   for (i = 0; i < n_basic_blocks; i++)
  24200. +     {
  24201. +       if (blocks_visited[i] && i != source_blocknum)
  24202. +     {
  24203. +       for (insn = basic_block_head[i];
  24204. +            insn && insn != death_blocks[i]
  24205. +            && insn != NEXT_INSN (basic_block_end[i]);
  24206. +            insn = NEXT_INSN (insn))
  24207. +         {
  24208. +           if (GET_CODE (insn) == INSN)
  24209. +         {
  24210. +           if (reg_used_in_body (regno, PATTERN (insn)))
  24211. +             {
  24212. +               ret_val = 0;
  24213. +               if (stack_reg_dump_file)
  24214. +             {
  24215. +               fprintf (stack_reg_dump_file,
  24216. +                    "  reg used in body of insn %d\n", INSN_UID (insn));
  24217. +             }
  24218. +               if (GET_CODE (PATTERN (insn)) == PARALLEL
  24219. +             && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
  24220. +             {
  24221. +               cmp_part = XVECEXP (PATTERN (insn), 0, 0);
  24222. +               last_set_insn = NULL;
  24223. +               if (SET_DEST (cmp_part) == cc0_rtx
  24224. +                   && GET_CODE (SET_SRC (cmp_part)) == COMPARE
  24225. +                   && (GET_MODE (SET_SRC (cmp_part)) == CCmode
  24226. +                       || GET_MODE (SET_SRC (cmp_part)) == CCFPEQmode
  24227. +                       || GET_MODE (SET_SRC (cmp_part)) == VOIDmode)
  24228. +                   && GET_CODE (XEXP (SET_SRC (cmp_part), 0)) == REG
  24229. +                   && REGNO (XEXP (SET_SRC (cmp_part), 0)) == regno
  24230. +                   && (GET_CODE (XEXP (SET_SRC (cmp_part), 1)) != REG
  24231. +                       || GET_MODE (SET_SRC (cmp_part)) == CCFPEQmode)
  24232. +                   && !reg_last_loaded (i, PREV_INSN (insn),
  24233. +                        REGNO (XEXP (SET_SRC (cmp_part), 0)),
  24234. +                            &last_set_insn)
  24235. +                   && !last_set_insn
  24236. +                   && tests_equality (NEXT_INSN (insn)))
  24237. +                 {
  24238. +                   *used_in_cmp = 1;
  24239. +                 }
  24240. +               else
  24241. +                 {
  24242. +                   *only_cmp = 0;
  24243. +                 }
  24244. +             }
  24245. +               else
  24246. +             {
  24247. +               *only_cmp = 0;
  24248. +             }
  24249. +             }
  24250. +         }
  24251. +         }
  24252. +     }
  24253. +     }
  24254. +   return (ret_val);
  24255. + }
  24256. + /*
  24257. +   If regno is used in insn is anyway except as a dest or source of a set
  24258. +     return 1
  24259. +   else
  24260. +     return 0
  24261. + */
  24262. + static int
  24263. + reg_used_in_body (regno, body)
  24264. +      int regno;
  24265. +      rtx body;
  24266. + {
  24267. +   int i, ret_val = 0;
  24268. +   if (GET_CODE (body) == SET)
  24269. +     {
  24270. +       if (GET_CODE (SET_DEST (body)) != REG)
  24271. +     {
  24272. +       if (reg_overlap_mentioned_p (regno_reg_rtx[regno],
  24273. +                        SET_DEST (body)))
  24274. +         {
  24275. +           return (1);
  24276. +         }
  24277. +     }
  24278. +       else if (REGNO (SET_DEST (body)) == regno)
  24279. +     {
  24280. +       if (GET_CODE (SET_SRC (body)) != MEM
  24281. +           && GET_CODE (SET_SRC (body)) != REG
  24282. +           && GET_CODE (SET_SRC (body)) != CONST_DOUBLE)
  24283. +         {
  24284. +           return (1);
  24285. +         }
  24286. +     }
  24287. +       if (GET_CODE (SET_SRC (body)) != REG)
  24288. +     {
  24289. +       if (reg_overlap_mentioned_p (regno_reg_rtx[regno],
  24290. +                        SET_SRC (body)))
  24291. +         {
  24292. +           return (1);
  24293. +         }
  24294. +     }
  24295. +       else if (REGNO (SET_SRC (body)) == regno)
  24296. +     {
  24297. +       if (/*GET_CODE (SET_DEST (body)) != REG
  24298. +           && */ GET_CODE (SET_DEST (body)) != MEM)
  24299. +         {
  24300. +           return (1);
  24301. +         }
  24302. +     }
  24303. +       return (0);
  24304. +     }
  24305. +   else if (GET_CODE (body) == CLOBBER)
  24306. +     {
  24307. +       if (GET_CODE (SET_DEST (body)) == REG && REGNO (SET_DEST (body)) == regno)
  24308. +     {
  24309. +       return (1);
  24310. +     }
  24311. +       return (0);
  24312. +     }
  24313. +   else if (GET_CODE (body) == PARALLEL)
  24314. +     {
  24315. +       for (i = 0; i < XVECLEN (body, 0); i++)
  24316. +     {
  24317. +       ret_val |= reg_used_in_body (regno, XVECEXP (body, 0, i));
  24318. +       if (ret_val)
  24319. +         {
  24320. +           return (1);
  24321. +         }
  24322. +     }
  24323. +       return (ret_val);
  24324. +     }
  24325. +   else
  24326. +     {
  24327. +       return (1);
  24328. +     }
  24329. + }
  24330. + /*
  24331. +    If the stack reg regno has not already been allocated a temp slot then
  24332. +      allocate one for it. 
  24333. +    Store the last value of regno in block# source_blocknum into it's
  24334. +    temp_slot.  
  24335. +    Mark the last use of regno in the block as REG_DEAD
  24336. + */
  24337. + static int
  24338. + store_into_temp (regno, source_blocknum)
  24339. +      int regno, source_blocknum;
  24340. + {
  24341. +   rtx last_set, last_use, stack_slot, store_rtx, store_insn, note;
  24342. +   int found, insn_code_num, i;
  24343. +   register int offset;
  24344. +   register int bit;
  24345. +   register int compl_bit;
  24346. +   /* Find where regno is last set in source_blocknum */
  24347. +   last_set = basic_block_end[source_blocknum];
  24348. +   found = 0;
  24349. +   while (!found && last_set != PREV_INSN (basic_block_head[source_blocknum]))
  24350. +     {
  24351. +       if (GET_CODE (last_set) == INSN)
  24352. +     {
  24353. +       if (GET_CODE (PATTERN (last_set)) == PARALLEL)
  24354. +         {
  24355. +           for (i = 0; i < XVECLEN (PATTERN (last_set), 0); i++)
  24356. +         {
  24357. +           if (GET_CODE (XVECEXP (PATTERN (last_set), 0, i)) == SET)
  24358. +             {
  24359. +               if (GET_CODE (SET_DEST (XVECEXP (PATTERN (last_set), 0, i))) == REG &&
  24360. +               REGNO (SET_DEST (XVECEXP (PATTERN (last_set), 0, i))) == regno)
  24361. +             {
  24362. +               return (0);
  24363. +             }
  24364. +             }
  24365. +           else if (GET_CODE (XVECEXP (PATTERN (last_set), 0, i)) == CLOBBER)
  24366. +             {
  24367. +               if (GET_CODE (SET_DEST (XVECEXP (PATTERN (last_set), 0, i))) == REG &&
  24368. +               REGNO (SET_DEST (XVECEXP (PATTERN (last_set), 0, i))) == regno)
  24369. +             {
  24370. +               return (0);
  24371. +             }
  24372. +             }
  24373. +           else
  24374. +             {
  24375. +               return (0);
  24376. +             }
  24377. +         }
  24378. +         }
  24379. +       if ((GET_CODE (PATTERN (last_set)) == SET ||
  24380. +            GET_CODE (PATTERN (last_set)) == CLOBBER) &&
  24381. +           GET_CODE (SET_DEST (PATTERN (last_set))) == REG &&
  24382. +           REGNO (SET_DEST (PATTERN (last_set))) == regno)
  24383. +         {
  24384. +           if (GET_CODE (PATTERN (last_set)) == CLOBBER)
  24385. +         return (0);
  24386. +           if (GET_CODE (SET_SRC (PATTERN (last_set))) != MEM)
  24387. +         return (0);
  24388. +           found = 1;
  24389. +         }
  24390. +     }
  24391. +       if (!found)
  24392. +     {
  24393. +       last_set = PREV_INSN (last_set);
  24394. +     }
  24395. +     }
  24396. +   if (!found)
  24397. +     {
  24398. +       return (0);
  24399. +     }
  24400. +   /* Allocate a temp slot and store the value that is loaded into
  24401. +      regno at last_set into that temp slot and place the insn to
  24402. +      do this right after the load to regno */
  24403. +   if (reg_temp_slot[regno] == NULL)
  24404. +     {
  24405. + #ifdef SPARE_REGS
  24406. +       if (max_reg_num () < max_regno)
  24407. +         {
  24408. +           if (GET_MODE (SET_DEST (PATTERN (last_set))) == SFmode)
  24409. +             {
  24410. +               reg_temp_slot[regno] = gen_reg_rtx (SImode);
  24411. +             }
  24412. +           else
  24413. +             reg_temp_slot[regno] 
  24414. +           = assign_stack_local (GET_MODE (SET_DEST (PATTERN (last_set))),
  24415. +            GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (last_set)))),
  24416. +                 -1);
  24417. +         }
  24418. +       else
  24419. + #endif
  24420. +         reg_temp_slot[regno] 
  24421. +       = assign_stack_local (GET_MODE (SET_DEST (PATTERN (last_set))),
  24422. +            GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (last_set)))),
  24423. +                 -1);
  24424. +     }
  24425. +   store_rtx = gen_rtx (SET, 0, reg_temp_slot[regno],
  24426. +                copy_rtx (SET_SRC (PATTERN (last_set))));
  24427. +   if (GET_CODE (reg_temp_slot[regno]) == REG )
  24428. +     {
  24429. +       if (GET_CODE (SET_SRC (store_rtx)) == CONST_DOUBLE)
  24430. +         {
  24431. +           union
  24432. +             {
  24433. +               int i[2];
  24434. +               double d;
  24435. +             }
  24436. +           u1;
  24437. +           union
  24438. +             {
  24439. +               int i;
  24440. +               float f;
  24441. +             }
  24442. +           u2;
  24443. +           u1.i[0] = CONST_DOUBLE_LOW (SET_SRC (store_rtx));
  24444. +           u1.i[1] = CONST_DOUBLE_HIGH (SET_SRC (store_rtx));
  24445. +           u2.f = u1.d;
  24446. +           SET_SRC (store_rtx) = 
  24447. +             gen_rtx (CONST_INT, 0, u2.i);
  24448. +         }
  24449. +       else
  24450. +         {
  24451. +           PUT_MODE (SET_SRC (store_rtx), GET_MODE (reg_temp_slot[regno]));
  24452. +         }
  24453. +       reg_n_sets[REGNO (reg_temp_slot[regno])]++;
  24454. +       reg_n_refs[REGNO (reg_temp_slot[regno])]++;
  24455. +       reg_live_length[REGNO (reg_temp_slot[regno])] = 2;
  24456. +     }
  24457. +   insn_code_num = recog (store_rtx, last_set);
  24458. +   if (insn_code_num < 0)
  24459. +     {
  24460. +       return (0);
  24461. +     }
  24462. +   store_insn = emit_insn_after (store_rtx, PREV_INSN (last_set));
  24463. +   INSN_CODE (store_insn) = insn_code_num;
  24464. +   /* Find where regno is last use in source_blocknum */
  24465. +   last_use = basic_block_end[source_blocknum];
  24466. +   found = 0;
  24467. +   while (!found && last_use != PREV_INSN (basic_block_head[source_blocknum]))
  24468. +     {
  24469. +       if (GET_CODE (last_use) == INSN)
  24470. +     {
  24471. +       if (reg_overlap_mentioned_p (regno_reg_rtx[regno], PATTERN (last_use)))
  24472. +         {
  24473. +           found = 1;
  24474. +         }
  24475. +     }
  24476. +       if (!found)
  24477. +     {
  24478. +       last_use = PREV_INSN (last_use);
  24479. +     }
  24480. +     }
  24481. +   offset = regno / REGSET_ELT_BITS;
  24482. +   bit = 1 << (regno % REGSET_ELT_BITS);
  24483. +   compl_bit = ~bit;
  24484. +   if (!found)
  24485. +     { /* regno was only loaded and never used - the load can be deleted */
  24486. +       delete_insn_for_stacker (last_set);
  24487. +       basic_block_maybe_live_at_end[source_blocknum][offset] &= compl_bit;
  24488. +       return (1);
  24489. +     }
  24490. +   /* Mark regno as dead at last_use */
  24491. +   note = gen_rtx (EXPR_LIST, REG_DEAD, regno_reg_rtx[regno],
  24492. +           REG_NOTES (last_use));
  24493. +   XEXP (note, 1) = REG_NOTES (last_use);
  24494. +   REG_NOTES (last_use) = note;
  24495. +   basic_block_maybe_live_at_end[source_blocknum][offset] &= compl_bit;
  24496. +   return (1);
  24497. + }
  24498. + /*
  24499. +   Starting at block# block_num visit all successor blocks recursively
  24500. +   stopping at a block where regno is not live at exit or regno
  24501. +   is set in block
  24502. + */
  24503. + static int
  24504. + visit_till_dies (regno, block_num)
  24505. +      int regno, block_num;
  24506. + {
  24507. +   register int offset = regno / REGSET_ELT_BITS;
  24508. +   register int bit = 1 << (regno % REGSET_ELT_BITS);
  24509. +   int ret_val = 1;
  24510. +   int already_visited;
  24511. +   rtx reg_death = NULL;
  24512. +   already_visited = blocks_visited[block_num];
  24513. +   blocks_visited[block_num] = 1;
  24514. +   if (num_visits > n_basic_blocks * 2)
  24515. +     { /* Failed to find where regno dies */
  24516. +       return (0);
  24517. +     }
  24518. +   if (already_visited)
  24519. +     {
  24520. +       num_visits++;
  24521. +       return (1);
  24522. +     }
  24523. +   num_visits++;
  24524. +   if ((basic_block_maybe_live_at_end[block_num][offset] & bit)
  24525. +       && !(reg_death = reg_dies_in_block (regno, block_num)))
  24526. +     {
  24527. +       if (jump_target_block[block_num] != -1)
  24528. +     {
  24529. +       ret_val = visit_till_dies (regno, jump_target_block[block_num]);
  24530. +     }
  24531. +       if (ret_val && fall_thru_block[block_num] != -1)
  24532. +     {
  24533. +       ret_val = visit_till_dies (regno, fall_thru_block[block_num]);
  24534. +     }
  24535. +       return (ret_val);
  24536. +     }
  24537. +   else
  24538. +     {
  24539. +       if (reg_death)
  24540. +     {
  24541. +       death_blocks[block_num] = NEXT_INSN (reg_death);
  24542. +     }
  24543. +       return (1);
  24544. +     }
  24545. + }
  24546. + /* Return the insn where regno dies in the block if it does,
  24547. +    otherwise return NULL
  24548. + */
  24549. + static rtx
  24550. + reg_dies_in_block (regno, block_num)
  24551. +      int regno, block_num;
  24552. + {
  24553. +   rtx insn;
  24554. +   for (insn = basic_block_head[block_num];
  24555. +        insn && insn != NEXT_INSN (basic_block_end[block_num]);
  24556. +        insn = NEXT_INSN (insn))
  24557. +     {
  24558. +       if (GET_CODE (insn) == INSN && find_regno_note (insn, REG_DEAD, regno))
  24559. +     {
  24560. +       return (insn);
  24561. +     }
  24562. +     }
  24563. +   return (NULL);
  24564. + }
  24565. + my_dump_block_info ()
  24566. + {
  24567. +   int i;
  24568. +   int max_regno = max_reg_num();
  24569. +   for (i = 0; i < n_basic_blocks; i++)
  24570. +     {
  24571. +       register rtx head, jump;
  24572. +       register int regno;
  24573. +       fprintf (stack_reg_dump_file, "\nBasic block %d: first insn %d, last %d.\n",
  24574. +            i,
  24575. +            INSN_UID (basic_block_head[i]),
  24576. +            INSN_UID (basic_block_end[i]));
  24577. +       /* The control flow graph's storage is freed
  24578. +      now when flow_analysis returns.
  24579. +      Don't try to print it if it is gone.  */
  24580. +       fprintf (stack_reg_dump_file, "Succesor blocks: %d %d\n",
  24581. +            fall_thru_block[i], jump_target_block[i]);
  24582. +       fprintf (stack_reg_dump_file, "\nRegisters live at start:");
  24583. +       for (regno = 0; regno < max_regno; regno++)
  24584. +     {
  24585. +       register int offset = regno / REGSET_ELT_BITS;
  24586. +       register int bit = 1 << (regno % REGSET_ELT_BITS);
  24587. +       if (basic_block_live_at_start[i][offset] & bit)
  24588. +         {
  24589. +           fprintf (stack_reg_dump_file, " %d", regno);
  24590. +         }
  24591. +     }
  24592. +       fprintf (stack_reg_dump_file, "\n");
  24593. +       fprintf (stack_reg_dump_file, "Registers live at end:");
  24594. +       for (regno = 0; regno < max_regno; regno++)
  24595. +     {
  24596. +       register int offset = regno / REGSET_ELT_BITS;
  24597. +       register int bit = 1 << (regno % REGSET_ELT_BITS);
  24598. +       if (basic_block_maybe_live_at_end[i][offset] & bit)
  24599. +         {
  24600. +           fprintf (stack_reg_dump_file, " %d", regno);
  24601. +         }
  24602. +     }
  24603. +       fprintf (stack_reg_dump_file, "\n");
  24604. +     }
  24605. +   fprintf (stack_reg_dump_file, "\n");
  24606. + }
  24607. + #define   MINUS0  0x80000000
  24608. + /*
  24609. +   change floating point compares to integer compares
  24610. + */
  24611. + void
  24612. + float_to_int_cmp (f, allow_new_jumps)
  24613. +      rtx f;
  24614. + {
  24615. +   union
  24616. +     {
  24617. +       int i[2];
  24618. +       double d;
  24619. +     }
  24620. +   u1;
  24621. +   union
  24622. +     {
  24623. +       int i;
  24624. +       float f;
  24625. +     }
  24626. +   u2;
  24627. +   int block, found, next_is_ok, rev_new_targets, const_is_zero, no_new_jump,
  24628. +       change_org_jump, new_org_cond, rev_org_targets, new_jump_cond,
  24629. +       make_new_lab, new_lab_true;
  24630. +   rtx insn, sf_reg, sf_dead_note, last_set, mem_loaded, int_cmp, cmp_part,
  24631. +       op1, next, org_jump_insn, double_const, tmp, new_jump,  new_jump_insn, 
  24632. +       new_label, new_label_insn, gen_cmpsi_1 ();
  24633. +   if (HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
  24634. +       || HOST_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
  24635. +     {
  24636. +       return;
  24637. +     }
  24638. +   if (TARGET_IEEE_FP)
  24639. +     {
  24640. +       return;
  24641. +     }
  24642. +   insn = f;
  24643. +   for (insn; insn != NULL; insn = NEXT_INSN (insn))
  24644. +     {
  24645. +       if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == PARALLEL)
  24646. +     {
  24647. +       if (GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
  24648. +         {
  24649. +           cmp_part = XVECEXP (PATTERN (insn), 0, 0);
  24650. +           if (SET_DEST (cmp_part) == cc0_rtx
  24651. +           && GET_CODE (SET_SRC (cmp_part)) == COMPARE
  24652. +           && (GET_MODE (SET_SRC (cmp_part)) == CCmode
  24653. +               || GET_MODE (SET_SRC (cmp_part)) == VOIDmode)
  24654. +           && ( 
  24655. +               (GET_CODE (XEXP (SET_SRC (cmp_part), 0)) == FLOAT_EXTEND
  24656. +                && GET_CODE (XEXP (XEXP (SET_SRC (cmp_part), 0), 0)) == REG
  24657. +                && REGNO (XEXP (XEXP (SET_SRC (cmp_part), 0), 0)) == FIRST_FLOAT_REG
  24658. +                    && GET_MODE (XEXP (XEXP (SET_SRC (cmp_part), 0), 0)) == SFmode)
  24659. +                   || /* Will have to make sure later it was loaded 
  24660. +                         from SFmode */
  24661. +               (GET_CODE (XEXP (SET_SRC (cmp_part), 0)) == REG
  24662. +                && REGNO (XEXP (SET_SRC (cmp_part), 0)) == FIRST_FLOAT_REG
  24663. +                    && GET_MODE (XEXP (SET_SRC (cmp_part), 0)) == DFmode)
  24664. +                  )
  24665. +           && GET_CODE (XEXP (SET_SRC (cmp_part), 1)) == MEM)
  24666. +         {
  24667. +           if (CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (SET_SRC (cmp_part), 1), 0)))
  24668. +             {
  24669. +               double_const
  24670. +             = get_pool_constant (XEXP (XEXP (SET_SRC (cmp_part), 1), 0));
  24671. +               if (GET_CODE (double_const) == CONST_DOUBLE)
  24672. +             {
  24673. +               u1.i[0] = CONST_DOUBLE_LOW (double_const);
  24674. +               u1.i[1] = CONST_DOUBLE_HIGH (double_const);
  24675. +               u2.f = u1.d;
  24676. +               if (GET_CODE (XEXP (SET_SRC (cmp_part), 0)) == FLOAT_EXTEND)
  24677. +                 sf_reg = XEXP (XEXP (SET_SRC (cmp_part), 0), 0);
  24678. +               else
  24679. +                 sf_reg = XEXP (SET_SRC (cmp_part), 0);
  24680. +               sf_dead_note
  24681. +                 = find_regno_note (insn, REG_DEAD, REGNO (sf_reg));
  24682. +             }
  24683. +               else
  24684. +             {
  24685. +               double_const = NULL;
  24686. +               sf_dead_note = NULL;
  24687. +             }
  24688. +             }
  24689. +           else
  24690. +             {
  24691. +               double_const = NULL;
  24692. +               sf_dead_note = NULL;
  24693. +             }
  24694. +           next_is_ok = 1;
  24695. +           no_new_jump = 0;
  24696. +           const_is_zero = 0;
  24697. +           if (u1.d == 0.0)
  24698. +             {  /* 0.0 needs special handling because -0.0 has
  24699. +                   a different representation */
  24700. +               const_is_zero = 1;
  24701. +               next_is_ok = 0;
  24702. +               rev_new_targets = 0;
  24703. +               change_org_jump = 0;
  24704. +               rev_org_targets = 0;
  24705. +               new_jump_cond = EQ;
  24706. +               make_new_lab = 0;
  24707. +               new_lab_true = 0;
  24708. +               next = NEXT_INSN (insn);
  24709. +               if (allow_new_jumps
  24710. +                   && GET_CODE (next) == JUMP_INSN
  24711. +                   && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
  24712. +             {
  24713. +               org_jump_insn = next;
  24714. +               if (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == LT
  24715. +                   && XEXP (SET_SRC (PATTERN (next)), 1) == pc_rtx
  24716. +                   && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
  24717. +                   && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx)
  24718. +                 {
  24719. +                   next_is_ok = 1;
  24720. +                   rev_new_targets = 1;
  24721. +                 }              
  24722. +               else if (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == GT
  24723. +                   && XEXP (SET_SRC (PATTERN (next)), 1) == pc_rtx
  24724. +                   && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
  24725. +                   && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx)
  24726. +                 {
  24727. +                   next_is_ok = 1;
  24728. +                   rev_new_targets = 1;
  24729. +                   change_org_jump = 1;
  24730. +                   new_org_cond = LE;
  24731. +                   rev_org_targets = 1;
  24732. +                   no_new_jump = 1;
  24733. +                 } 
  24734. +               else if (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == EQ
  24735. +                   && XEXP (SET_SRC (PATTERN (next)), 1) == pc_rtx
  24736. +                   && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
  24737. +                   && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx)
  24738. +                 {
  24739. +                   next_is_ok = 1;
  24740. +                   new_jump_cond = NE;
  24741. +                   rev_new_targets = 1;
  24742. +                   /* The original jump will jump to the new
  24743. +                      label, that will be placed immediately
  24744. +                      after the new jump.  */
  24745. +                   make_new_lab = 1;
  24746. +                   /* The new label is to be jumped to
  24747. +                      if the condition is true */
  24748. +                   new_lab_true = 1;
  24749. +                 } 
  24750. +               else if (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == NE
  24751. +                   && XEXP (SET_SRC (PATTERN (next)), 1) != pc_rtx
  24752. +                   && XEXP (SET_SRC (PATTERN (next)), 2) == pc_rtx
  24753. +                   && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
  24754. +                   && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx)
  24755. +                 {
  24756. +                   next_is_ok = 1;
  24757. +                   change_org_jump = 1;
  24758. +                   new_org_cond = EQ;
  24759. +                   new_jump_cond = NE;
  24760. +                   /* The original jump will jump to the new
  24761. +                      label, that will be placed immediately
  24762. +                      after the new jump.  */
  24763. +                   make_new_lab = 1;
  24764. +                   /* The new label is to be jumped to
  24765. +                      if the condition is true */
  24766. +                   new_lab_true = 1;
  24767. +                 } 
  24768. +               else if ((GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == GE
  24769. +                         && XEXP (SET_SRC (PATTERN (next)), 1) == pc_rtx
  24770. +                         && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
  24771. +                         && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx)
  24772. +                        ||
  24773. +                        (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == LT
  24774. +                         && XEXP (SET_SRC (PATTERN (next)), 1) != pc_rtx
  24775. +                         && XEXP (SET_SRC (PATTERN (next)), 2) == pc_rtx
  24776. +                         && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
  24777. +                         && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx))
  24778. +                 {
  24779. +                   next_is_ok = 1;
  24780. +                   change_org_jump = 1;
  24781. +                   new_org_cond = GE;
  24782. +                   new_jump_cond = NE;
  24783. +                   rev_new_targets = 1;
  24784. +                   /* The original jump will jump to the new
  24785. +                      label, that will be placed immediately
  24786. +                      after the new jump.  */
  24787. +                   make_new_lab = 1;
  24788. +                   /* The new label is to be jumped to
  24789. +                      if the condition is true */
  24790. +                   new_lab_true = 1;
  24791. +                 } 
  24792. +               else if (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == GT
  24793. +                        && XEXP (SET_SRC (PATTERN (next)), 1) != pc_rtx
  24794. +                        && XEXP (SET_SRC (PATTERN (next)), 2) == pc_rtx
  24795. +                        && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
  24796. +                        && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx)
  24797. +                 {
  24798. +                   next_is_ok = 1;
  24799. +                   no_new_jump = 1;
  24800. +                 }
  24801. +               else if ((GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == GE
  24802. +                         || GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == EQ)
  24803. +                        && XEXP (SET_SRC (PATTERN (next)), 1) != pc_rtx
  24804. +                        && XEXP (SET_SRC (PATTERN (next)), 2) == pc_rtx
  24805. +                        && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
  24806. +                        && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx)
  24807. +                 {
  24808. +                   next_is_ok = 1;
  24809. +                 }
  24810. +               else if (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == NE
  24811. +                        && XEXP (SET_SRC (PATTERN (next)), 1) == pc_rtx
  24812. +                        && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
  24813. +                        && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx)
  24814. +                 {
  24815. +                   next_is_ok = 1;
  24816. +                 }
  24817. +               else if (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == LE)
  24818. +                 {
  24819. +                   next_is_ok = 1;
  24820. +                   no_new_jump = 1;
  24821. +                 }
  24822. +             }
  24823. +             }
  24824. +           if (sf_dead_note
  24825. +               && next_is_ok
  24826. +               && u1.d >= 0.0
  24827. +               && ((double) u2.f == u1.d)
  24828. +               && ((float) u1.d == u2.f))
  24829. +             { /* Find where the sf_reg was loaded from.  */
  24830. +               last_set = PREV_INSN (insn);
  24831. +               found = 0;
  24832. +               while (!found && last_set)
  24833. +             {
  24834. +               if (GET_CODE (last_set) == INSN)
  24835. +                 {
  24836. +                   if (GET_CODE (PATTERN (last_set)) == SET
  24837. +                   && rtx_equal_p (sf_reg,
  24838. +                           SET_DEST (PATTERN (last_set)))
  24839. +                       &&
  24840. +                       (GET_CODE (SET_SRC (PATTERN (last_set))) 
  24841. +                           == MEM ||
  24842. +                        (GET_CODE (SET_SRC (PATTERN (last_set))) 
  24843. +                          == FLOAT_EXTEND 
  24844. +                         &&
  24845. +                         GET_CODE (XEXP (SET_SRC (PATTERN (last_set)),0))
  24846. +                                   == MEM)
  24847. +                   ))
  24848. +                 {
  24849. +                   if (GET_CODE (SET_SRC (PATTERN (last_set))) 
  24850. +                            == FLOAT_EXTEND)
  24851. +                         {
  24852. +                           mem_loaded = 
  24853. +                             XEXP (SET_SRC (PATTERN (last_set)),0);
  24854. +                       found = 1;
  24855. +                         }
  24856. +                       else if (GET_CODE (XEXP (SET_SRC (cmp_part), 0)) 
  24857. +                                == FLOAT_EXTEND)
  24858. +                         {
  24859. +                           mem_loaded = 
  24860. +                             SET_SRC (PATTERN (last_set));
  24861. +                       found = 1;
  24862. +                         }
  24863. +                       else
  24864. +                         {
  24865. +                           last_set = NULL;
  24866. +                         }
  24867. +                 }
  24868. +                    else if (GET_CODE (PATTERN (last_set)) == SET
  24869. +                             && GET_CODE (SET_DEST (PATTERN (last_set)))
  24870. +                                 == REG
  24871. +                             && !IS_STACK_MODE (
  24872. +                                  GET_MODE (SET_DEST (PATTERN (last_set)))))
  24873. +                      {
  24874. +                        last_set = PREV_INSN (last_set);
  24875. +                      }
  24876. +                   else
  24877. +                 last_set = NULL;
  24878. +                 }
  24879. +               else if (GET_CODE (last_set) == NOTE)
  24880. +                 {
  24881. +                   last_set = PREV_INSN (last_set);
  24882. +                 }
  24883. +               else
  24884. +                 last_set = NULL;
  24885. +             }
  24886. +               if (last_set)
  24887. +             {
  24888. +               op1 = gen_rtx (MEM, SImode, XEXP (mem_loaded,0));
  24889. +               /* See if op1 is also in a register.  */
  24890. +               if (next_nonnote_insn (last_set) == insn)
  24891. +                 {
  24892. +                   tmp = prev_nonnote_insn (last_set);
  24893. +                 }
  24894. +               else
  24895. +                 {
  24896. +                   tmp = next_nonnote_insn (last_set);
  24897. +                   if (next_nonnote_insn (tmp) != insn)
  24898. +                     {
  24899. +                       tmp = NULL;
  24900. +                     }
  24901. +                 }
  24902. +               if (tmp
  24903. +                   && GET_CODE (tmp) == INSN
  24904. +                   && GET_CODE (PATTERN (tmp)) == SET
  24905. +                   && GET_CODE (SET_DEST (PATTERN (tmp))) == REG
  24906. +                   && rtx_equal_p (op1, 
  24907. +                                   SET_SRC (PATTERN (tmp))))
  24908. +                 {
  24909. +                   op1 = SET_DEST (PATTERN (tmp));
  24910. +                 }
  24911. +               int_cmp
  24912. +                 = gen_cmpsi_1 (op1,
  24913. +                           gen_rtx (CONST_INT, 0, u2.i));
  24914. +               PATTERN (insn) = int_cmp;
  24915. +               INSN_CODE (insn) = recog (int_cmp, insn);
  24916. +               remove_note (insn, sf_dead_note);
  24917. +               reg_n_deaths[REGNO (sf_reg)]--;
  24918. +               PUT_CODE (last_set, NOTE);
  24919. +               NOTE_LINE_NUMBER (last_set) = NOTE_INSN_DELETED;
  24920. +               NOTE_SOURCE_FILE (last_set) = 0;
  24921. +               if (const_is_zero && change_org_jump)
  24922. +                 {
  24923. +                   PUT_CODE (XEXP (SET_SRC (PATTERN (org_jump_insn)), 0), 
  24924. +                             new_org_cond);  
  24925. +                   INSN_CODE (org_jump_insn)
  24926. +                 = recog (PATTERN (org_jump_insn), org_jump_insn);
  24927. +                 }
  24928. +               if (const_is_zero && rev_org_targets)
  24929. +                 {
  24930. +                   tmp = XEXP (SET_SRC (PATTERN (org_jump_insn)), 1);
  24931. +                   XEXP (SET_SRC (PATTERN (org_jump_insn)), 1)
  24932. +                     = XEXP (SET_SRC (PATTERN (org_jump_insn)), 2);
  24933. +                   XEXP (SET_SRC (PATTERN (org_jump_insn)), 2) = tmp;
  24934. +                   INSN_CODE (org_jump_insn)
  24935. +                 = recog (PATTERN (org_jump_insn), org_jump_insn);
  24936. +                 }
  24937. +               if (const_is_zero && !no_new_jump)
  24938. +                 {
  24939. +                   new_jump = copy_rtx (PATTERN (next));
  24940. +                   PUT_CODE (XEXP (SET_SRC (new_jump), 0), new_jump_cond);
  24941. +                   if (rev_new_targets)
  24942. +                 {
  24943. +                   tmp = XEXP (SET_SRC (new_jump), 1);
  24944. +                   XEXP (SET_SRC (new_jump), 1)
  24945. +                     = XEXP (SET_SRC (new_jump), 2);
  24946. +                   XEXP (SET_SRC (new_jump), 2) = tmp;
  24947. +                 }
  24948. +                   int_cmp
  24949. +                 = gen_cmpsi_1 (op1,
  24950. +                         gen_rtx (CONST_INT, 0, MINUS0));
  24951. +                   int_cmp
  24952. +                 = emit_insn_before (int_cmp, NEXT_INSN (next));
  24953. +                   INSN_CODE (int_cmp) = INSN_CODE (insn);
  24954. +                   new_jump_insn
  24955. +                 = emit_jump_insn_after (new_jump, int_cmp);
  24956. +                   INSN_CODE (new_jump_insn)
  24957. +                 = recog (new_jump, new_jump_insn);
  24958. +                 }
  24959. +               if (const_is_zero && make_new_lab)
  24960. +                 {
  24961. +                   if (no_new_jump)
  24962. +                     abort ();
  24963. +                               new_label = gen_label_rtx ();
  24964. +                               new_label_insn 
  24965. +                                 = emit_label_after (new_label, new_jump_insn);
  24966. +                               ++LABEL_NUSES (new_label_insn);
  24967. +                               JUMP_LABEL (org_jump_insn) = new_label_insn;
  24968. +                               if (new_lab_true)
  24969. +                                 {
  24970. +                       XEXP (SET_SRC (PATTERN (org_jump_insn)), 1)
  24971. +                         = gen_rtx (LABEL_REF, VOIDmode, new_label);
  24972. +                       XEXP (SET_SRC (PATTERN (org_jump_insn)), 2)
  24973. +                         = pc_rtx;
  24974. +                                 }
  24975. +                               else
  24976. +                                 {
  24977. +                       XEXP (SET_SRC (PATTERN (org_jump_insn)), 1)
  24978. +                         = pc_rtx;
  24979. +                       XEXP (SET_SRC (PATTERN (org_jump_insn)), 2)
  24980. +                         = gen_rtx (LABEL_REF, VOIDmode, new_label);
  24981. +                                 }
  24982. +                   INSN_CODE (org_jump_insn)
  24983. +                  = recog (PATTERN (org_jump_insn), org_jump_insn);
  24984. +                 }
  24985. +             }
  24986. +             }
  24987. +         }
  24988. +         }
  24989. +     }
  24990. +     }
  24991. + }
  24992. + #endif
  24993.   #endif /* STACK_REGS */
  24994. diff -rNci gcc-2.7.2/reload.c gcc-2.7.2p/reload.c
  24995. *** gcc-2.7.2/reload.c    Sat Nov 11 13:23:54 1995
  24996. --- gcc-2.7.2p/reload.c    Tue Jan 23 09:25:30 1996
  24997. ***************
  24998. *** 98,104 ****
  24999.   #include "hard-reg-set.h"
  25000.   #include "flags.h"
  25001.   #include "real.h"
  25002. - #include "output.h"
  25003.   
  25004.   #ifndef REGISTER_MOVE_COST
  25005.   #define REGISTER_MOVE_COST(x, y) 2
  25006. --- 98,103 ----
  25007. ***************
  25008. *** 357,372 ****
  25009.   
  25010.     *picode = CODE_FOR_nothing;
  25011.   
  25012. -   /* If X is a paradoxical SUBREG, use the inner value to determine both the
  25013. -      mode and object being reloaded.  */
  25014. -   if (GET_CODE (x) == SUBREG
  25015. -       && (GET_MODE_SIZE (GET_MODE (x))
  25016. -       > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
  25017. -     {
  25018. -       x = SUBREG_REG (x);
  25019. -       reload_mode = GET_MODE (x);
  25020. -     }
  25021.     /* If X is a pseudo-register that has an equivalent MEM (actually, if it
  25022.        is still a pseudo-register by now, it *must* have an equivalent MEM
  25023.        but we don't want to assume that), use that equivalent when seeing if
  25024. --- 356,361 ----
  25025. ***************
  25026. *** 735,741 ****
  25027.   {
  25028.     register int i;
  25029.     int dont_share = 0;
  25030. -   int dont_remove_subreg = 0;
  25031.     rtx *in_subreg_loc = 0, *out_subreg_loc = 0;
  25032.     int secondary_in_reload = -1, secondary_out_reload = -1;
  25033.     enum insn_code secondary_in_icode = CODE_FOR_nothing;
  25034. --- 724,729 ----
  25035. ***************
  25036. *** 902,915 ****
  25037.             != HARD_REGNO_NREGS (REGNO (SUBREG_REG (in)),
  25038.                          GET_MODE (SUBREG_REG (in)))))))
  25039.       {
  25040. -       /* This relies on the fact that emit_reload_insns outputs the
  25041. -      instructions for input reloads of type RELOAD_OTHER in the same
  25042. -      order as the reloads.  Thus if the outer reload is also of type
  25043. -      RELOAD_OTHER, we are guaranteed that this inner reload will be
  25044. -      output before the outer reload.  */
  25045.         push_reload (SUBREG_REG (in), NULL_RTX, &SUBREG_REG (in), NULL_PTR,
  25046.              GENERAL_REGS, VOIDmode, VOIDmode, 0, 0, opnum, type);
  25047. -       dont_remove_subreg = 1;
  25048.       }
  25049.   
  25050.   
  25051. --- 890,897 ----
  25052. ***************
  25053. *** 971,1006 ****
  25054.         outmode = GET_MODE (out);
  25055.       }
  25056.   
  25057. -   /* Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
  25058. -      either M1 is not valid for R or M2 is wider than a word but we only
  25059. -      need one word to store an M2-sized quantity in R.
  25060. -      However, we must reload the inner reg *as well as* the subreg in
  25061. -      that case.  In this case, the inner reg is an in-out reload.  */
  25062. -   if (out != 0 && GET_CODE (out) == SUBREG
  25063. -       && GET_CODE (SUBREG_REG (out)) == REG
  25064. -       && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
  25065. -       && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (out)), outmode)
  25066. -       || (GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
  25067. -           && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
  25068. -           > UNITS_PER_WORD)
  25069. -           && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
  25070. -            / UNITS_PER_WORD)
  25071. -           != HARD_REGNO_NREGS (REGNO (SUBREG_REG (out)),
  25072. -                        GET_MODE (SUBREG_REG (out)))))))
  25073. -     {
  25074. -       /* This relies on the fact that emit_reload_insns outputs the
  25075. -      instructions for output reloads of type RELOAD_OTHER in reverse
  25076. -      order of the reloads.  Thus if the outer reload is also of type
  25077. -      RELOAD_OTHER, we are guaranteed that this inner reload will be
  25078. -      output after the outer reload.  */
  25079. -       dont_remove_subreg = 1;
  25080. -       push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out),
  25081. -            &SUBREG_REG (out), ALL_REGS, VOIDmode, VOIDmode, 0, 0,
  25082. -            opnum, RELOAD_OTHER);
  25083. -     }
  25084.     /* If IN appears in OUT, we can't share any input-only reload for IN.  */
  25085.     if (in != 0 && out != 0 && GET_CODE (out) == MEM
  25086.         && (GET_CODE (in) == REG || GET_CODE (in) == MEM)
  25087. --- 953,958 ----
  25088. ***************
  25089. *** 1011,1026 ****
  25090.        simplifies some of the cases below.  */
  25091.   
  25092.     if (in != 0 && GET_CODE (in) == SUBREG && GET_CODE (SUBREG_REG (in)) == REG
  25093. !       && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
  25094. !       && ! dont_remove_subreg)
  25095.       in = gen_rtx (REG, GET_MODE (in),
  25096.             REGNO (SUBREG_REG (in)) + SUBREG_WORD (in));
  25097.   
  25098.     /* Similarly for OUT.  */
  25099.     if (out != 0 && GET_CODE (out) == SUBREG
  25100.         && GET_CODE (SUBREG_REG (out)) == REG
  25101. !       && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
  25102. !       && ! dont_remove_subreg)
  25103.       out = gen_rtx (REG, GET_MODE (out),
  25104.             REGNO (SUBREG_REG (out)) + SUBREG_WORD (out));
  25105.   
  25106. --- 963,976 ----
  25107.        simplifies some of the cases below.  */
  25108.   
  25109.     if (in != 0 && GET_CODE (in) == SUBREG && GET_CODE (SUBREG_REG (in)) == REG
  25110. !       && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER)
  25111.       in = gen_rtx (REG, GET_MODE (in),
  25112.             REGNO (SUBREG_REG (in)) + SUBREG_WORD (in));
  25113.   
  25114.     /* Similarly for OUT.  */
  25115.     if (out != 0 && GET_CODE (out) == SUBREG
  25116.         && GET_CODE (SUBREG_REG (out)) == REG
  25117. !       && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER)
  25118.       out = gen_rtx (REG, GET_MODE (out),
  25119.             REGNO (SUBREG_REG (out)) + SUBREG_WORD (out));
  25120.   
  25121. ***************
  25122. *** 4120,4125 ****
  25123. --- 4070,4079 ----
  25124.   {
  25125.     register int regno;
  25126.     rtx tem;
  25127. + #ifdef REWRITE_ADDRESS
  25128. +   /* intel1 */
  25129. +   rtx rewrite_address();
  25130. + #endif
  25131.   
  25132.     /* If the address is a register, see if it is a legitimate address and
  25133.        reload if not.  We first handle the cases where we need not reload
  25134. ***************
  25135. *** 4247,4261 ****
  25136.       return 0;
  25137.       }
  25138.   
  25139. !   /* If we have address of a stack slot but it's not valid because the
  25140. !      displacement is too large, compute the sum in a register.
  25141. !      Handle all base registers here, not just fp/ap/sp, because on some
  25142. !      targets (namely SH) we can also get too large displacements from
  25143. !      big-endian corrections.  */
  25144.     else if (GET_CODE (ad) == PLUS
  25145. !        && GET_CODE (XEXP (ad, 0)) == REG
  25146. !        && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
  25147. !        && REG_OK_FOR_BASE_P (XEXP (ad, 0))
  25148.          && GET_CODE (XEXP (ad, 1)) == CONST_INT)
  25149.       {
  25150.         /* Unshare the MEM rtx so we can safely alter it.  */
  25151. --- 4201,4217 ----
  25152.       return 0;
  25153.       }
  25154.   
  25155. !   /* If we have address of a stack slot but it's not valid
  25156. !      (displacement is too large), compute the sum in a register.  */
  25157.     else if (GET_CODE (ad) == PLUS
  25158. !        && (XEXP (ad, 0) == frame_pointer_rtx
  25159. ! #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
  25160. !            || XEXP (ad, 0) == hard_frame_pointer_rtx
  25161. ! #endif
  25162. ! #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
  25163. !            || XEXP (ad, 0) == arg_pointer_rtx
  25164. ! #endif
  25165. !            || XEXP (ad, 0) == stack_pointer_rtx)
  25166.          && GET_CODE (XEXP (ad, 1)) == CONST_INT)
  25167.       {
  25168.         /* Unshare the MEM rtx so we can safely alter it.  */
  25169. ***************
  25170. *** 4383,4388 ****
  25171. --- 4339,4375 ----
  25172.       }
  25173.       }
  25174.   
  25175. +   /* intel1 - even if one of the registers is still a pseudo
  25176. +              subst_reg_equivs may be able to substitute a
  25177. +              constant for it too */
  25178. +     else
  25179. +              
  25180. +     if (tem != ad && memory_address_p (mode, tem))
  25181. +       {
  25182. +         rtx tmp_rtx;
  25183. +         tmp_rtx = copy_rtx (tem);
  25184. +     /* Ok, we win that way.  Replace any additional eliminable
  25185. +        registers.  */
  25186. +     subst_reg_equivs_changed = 0;
  25187. +     tmp_rtx = subst_reg_equivs (tmp_rtx);
  25188. + #ifdef REWRITE_ADDRESS
  25189. +     if (!strict_memory_address_p (mode, tmp_rtx))
  25190. +       {
  25191. +             tmp_rtx = gen_rtx (MEM, mode, tmp_rtx);
  25192. +             REWRITE_ADDRESS (tmp_rtx);
  25193. +             tmp_rtx = XEXP (tmp_rtx, 0);
  25194. +       }
  25195. + #endif
  25196. +     /* Make sure that didn't make the address invalid again.  */
  25197. +     if (strict_memory_address_p (mode, tmp_rtx))
  25198. +       {
  25199. +         *loc = tmp_rtx;
  25200. +         return 0;
  25201. +       }
  25202. +     
  25203. +       }
  25204.     /* If constants aren't valid addresses, reload the constant address
  25205.        into a register.  */
  25206.     if (CONSTANT_P (ad) && ! strict_memory_address_p (mode, ad))
  25207. ***************
  25208. *** 4609,4626 ****
  25209.         {
  25210.           op0 = SUBREG_REG (op0);
  25211.           code0 = GET_CODE (op0);
  25212. -         if (code0 == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER)
  25213. -           op0 = gen_rtx (REG, word_mode,
  25214. -                  REGNO (op0) + SUBREG_WORD (orig_op0));
  25215.         }
  25216.   
  25217.       if (GET_CODE (op1) == SUBREG)
  25218.         {
  25219.           op1 = SUBREG_REG (op1);
  25220.           code1 = GET_CODE (op1);
  25221. -         if (code1 == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER)
  25222. -           op1 = gen_rtx (REG, GET_MODE (op1),
  25223. -                  REGNO (op1) + SUBREG_WORD (orig_op1));
  25224.         }
  25225.   
  25226.       if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE 
  25227. --- 4596,4607 ----
  25228. ***************
  25229. *** 4882,4918 ****
  25230.         return 0;
  25231.   
  25232.       case SUBREG:
  25233. !       if (GET_CODE (SUBREG_REG (x)) == REG)
  25234.       {
  25235. !       /* If this is a SUBREG of a hard register and the resulting register
  25236. !          is of the wrong class, reload the whole SUBREG.  This avoids
  25237. !          needless copies if SUBREG_REG is multi-word.  */
  25238. !       if (REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
  25239. !         {
  25240. !           int regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
  25241.   
  25242. !           if (! (context ? REGNO_OK_FOR_INDEX_P (regno)
  25243. !              : REGNO_OK_FOR_BASE_P (regno)))
  25244. !         {
  25245. !           push_reload (x, NULL_RTX, loc, NULL_PTR,
  25246. !                    context ? INDEX_REG_CLASS : BASE_REG_CLASS,
  25247. !                    GET_MODE (x), VOIDmode, 0, 0, opnum, type);
  25248. !           return 1;
  25249. !         }
  25250. !         }
  25251. !       /* If this is a SUBREG of a pseudo-register, and the pseudo-register
  25252. !          is larger than the class size, then reload the whole SUBREG.  */
  25253. !       else
  25254.           {
  25255. !           enum reg_class class = (context
  25256. !                       ? INDEX_REG_CLASS : BASE_REG_CLASS);
  25257. !           if (CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
  25258. !           > reg_class_size[class])
  25259. !         {
  25260. !           push_reload (x, NULL_RTX, loc, NULL_PTR, class,
  25261. !                    GET_MODE (x), VOIDmode, 0, 0, opnum, type);
  25262. !           return 1;
  25263. !         }
  25264.           }
  25265.       }
  25266.         break;
  25267. --- 4863,4883 ----
  25268.         return 0;
  25269.   
  25270.       case SUBREG:
  25271. !       /* If this is a SUBREG of a hard register and the resulting register is
  25272. !      of the wrong class, reload the whole SUBREG.  This avoids needless
  25273. !      copies if SUBREG_REG is multi-word.  */
  25274. !       if (GET_CODE (SUBREG_REG (x)) == REG
  25275. !       && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
  25276.       {
  25277. !       int regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
  25278.   
  25279. !       if (! (context ? REGNO_OK_FOR_INDEX_P (regno)
  25280. !          : REGNO_OK_FOR_BASE_P (regno)))
  25281.           {
  25282. !           push_reload (x, NULL_RTX, loc, NULL_PTR,
  25283. !                context ? INDEX_REG_CLASS : BASE_REG_CLASS,
  25284. !                GET_MODE (x), VOIDmode, 0, 0, opnum, type);
  25285. !           return 1;
  25286.           }
  25287.       }
  25288.         break;
  25289. ***************
  25290. *** 5193,5199 ****
  25291.              && refers_to_regno_for_reload_p (regno, endregno,
  25292.                           SUBREG_REG (SET_DEST (x)),
  25293.                           loc))
  25294. !           /* If the output is an earlyclobber operand, this is
  25295.            a conflict.  */
  25296.             || ((GET_CODE (SET_DEST (x)) != REG
  25297.              || earlyclobber_operand_p (SET_DEST (x)))
  25298. --- 5158,5164 ----
  25299.              && refers_to_regno_for_reload_p (regno, endregno,
  25300.                           SUBREG_REG (SET_DEST (x)),
  25301.                           loc))
  25302. !           /* If the ouput is an earlyclobber operand, this is
  25303.            a conflict.  */
  25304.             || ((GET_CODE (SET_DEST (x)) != REG
  25305.              || earlyclobber_operand_p (SET_DEST (x)))
  25306. ***************
  25307. *** 5597,5608 ****
  25308.             goal_mem
  25309.             || need_stable_sp))
  25310.       return 0;
  25311. - #ifdef NON_SAVING_SETJMP 
  25312. -       if (NON_SAVING_SETJMP && GET_CODE (p) == NOTE
  25313. -       && NOTE_LINE_NUMBER (p) == NOTE_INSN_SETJMP)
  25314. -     return 0;
  25315. - #endif
  25316.   
  25317.   #ifdef INSN_CLOBBERS_REGNO_P
  25318.         if ((valueno >= 0 && valueno < FIRST_PSEUDO_REGISTER
  25319. --- 5562,5567 ----
  25320. diff -rNci gcc-2.7.2/reload.h gcc-2.7.2p/reload.h
  25321. *** gcc-2.7.2/reload.h    Thu Jun 15 12:00:35 1995
  25322. --- gcc-2.7.2p/reload.h    Tue Jan 23 09:25:30 1996
  25323. ***************
  25324. *** 235,237 ****
  25325. --- 235,249 ----
  25326.   
  25327.   /* Find the places where hard regs are live across calls and save them.  */
  25328.   extern void save_call_clobbered_regs PROTO((enum machine_mode));
  25329. + /* intel1 */
  25330. + #define MAX_RELOAD_STACK_SLOTS 100
  25331. + struct reload_slot_info {
  25332. +     rtx  reload_stack_slot;
  25333. +     rtx  reload_insn;
  25334. +     rtx last_store;
  25335. +     int is_loaded_to_reg;
  25336. +     int stack_slot_pseudo_reg;
  25337. +     int cur_stack_offset;
  25338. +     char reload_stack_mode;
  25339. +     unsigned reload_slot_updated:1;
  25340. +     } ;
  25341. diff -rNci gcc-2.7.2/reload1.c gcc-2.7.2p/reload1.c
  25342. *** gcc-2.7.2/reload1.c    Sun Nov  5 16:22:22 1995
  25343. --- gcc-2.7.2p/reload1.c    Tue Jan 23 09:25:31 1996
  25344. ***************
  25345. *** 34,40 ****
  25346.   #include "recog.h"
  25347.   #include "basic-block.h"
  25348.   #include "output.h"
  25349. - #include "real.h"
  25350.   
  25351.   /* This file contains the reload pass of the compiler, which is
  25352.      run after register allocation has been done.  It checks that
  25353. --- 34,39 ----
  25354. ***************
  25355. *** 77,82 ****
  25356. --- 76,83 ----
  25357.   #ifndef MEMORY_MOVE_COST
  25358.   #define MEMORY_MOVE_COST(x) 4
  25359.   #endif
  25360. + /* intel1 */
  25361. + static int cur_stack_offset;
  25362.   
  25363.   /* During reload_as_needed, element N contains a REG rtx for the hard reg
  25364.      into which reg N has been reloaded (perhaps for a previous insn). */
  25365. ***************
  25366. *** 268,273 ****
  25367. --- 269,277 ----
  25368.   #define obstack_chunk_alloc xmalloc
  25369.   #define obstack_chunk_free free
  25370.   
  25371. + /* intel1 */
  25372. + extern FILE * global_reg_dump_file;
  25373.   /* List of labels that must never be deleted.  */
  25374.   extern rtx forced_labels;
  25375.   
  25376. ***************
  25377. *** 308,313 ****
  25378. --- 312,326 ----
  25379.   
  25380.   #define NUM_ELIMINABLE_REGS (sizeof reg_eliminate / sizeof reg_eliminate[0])
  25381.   
  25382. + /* intel1 */
  25383. + /* information for loop_after_global optimizations */
  25384. + struct reload_slot_info reload_slots[MAX_RELOAD_STACK_SLOTS];
  25385. + int num_reload_stack_slots=0;
  25386. + static rtx treplace_insn = NULL_RTX;
  25387. + /* is 1 is the pseudo has been spilled */
  25388. + int * pseudo_spilled;
  25389.   /* Record the number of pending eliminations that have an offset not equal
  25390.      to their initial offset.  If non-zero, we use a new copy of each
  25391.      replacement result in any insns encountered.  */
  25392. ***************
  25393. *** 372,377 ****
  25394. --- 385,392 ----
  25395.   static void inc_for_reload        PROTO((rtx, rtx, int));
  25396.   static int constraint_accepts_reg_p    PROTO((char *, rtx));
  25397.   static int count_occurrences        PROTO((rtx, rtx));
  25398. + /* intel1 */
  25399. + int is_a_param_slot();
  25400.   
  25401.   /* Initialize the reload pass once per compilation.  */
  25402.   
  25403. ***************
  25404. *** 466,471 ****
  25405. --- 481,506 ----
  25406.     /* The basic block number currently being processed for INSN.  */
  25407.     int this_block;
  25408.   
  25409. +   /* intel1 */
  25410. +   /* intel1. Look for insns whose src is equal to dest and delete them.  */
  25411. +   for (insn = next_nonnote_insn (first); insn; insn = next_nonnote_insn (insn))
  25412. +     {
  25413. +       if (GET_CODE (insn) == INSN 
  25414. +           && GET_CODE (PATTERN (insn)) == SET
  25415. +           && !(GET_CODE (SET_SRC (PATTERN (insn))) == MEM
  25416. +                && MEM_VOLATILE_P (SET_SRC (PATTERN (insn))))
  25417. +           && rtx_equal_p (SET_SRC (PATTERN (insn)), SET_DEST (PATTERN (insn))))
  25418. +         {
  25419. +       PUT_CODE (insn, NOTE);
  25420. +       NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
  25421. +       NOTE_SOURCE_FILE (insn) = 0;
  25422. +         }
  25423. +     }
  25424. +   num_reload_stack_slots = 0;
  25425. +   pseudo_spilled = (int *)alloca(max_regno*sizeof(int));
  25426. +   bzero(pseudo_spilled,max_regno*sizeof(int));
  25427. +   bzero(reload_slots,MAX_RELOADS*sizeof(struct reload_slot_info));
  25428.     /* Make sure even insns with volatile mem refs are recognizable.  */
  25429.     init_recog ();
  25430.   
  25431. ***************
  25432. *** 814,819 ****
  25433. --- 849,857 ----
  25434.   
  25435.         num_not_at_initial_offset = 0;
  25436.   
  25437. +       /* intel1 */
  25438. +       cur_stack_offset = 0;
  25439.         bzero ((char *) &offsets_known_at[get_first_label_num ()], num_labels);
  25440.   
  25441.         /* Set a known offset for each forced label to be at the initial offset
  25442. ***************
  25443. *** 1955,1960 ****
  25444. --- 1993,2034 ----
  25445.   
  25446.     reload_in_progress = 0;
  25447.   
  25448. +   /* intel1 */
  25449. +   for (insn = first; insn; insn = NEXT_INSN (insn))
  25450. +     {
  25451. +       if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
  25452. +           && GET_CODE (SET_DEST (PATTERN (insn))) == REG
  25453. +           && GET_CODE (SET_SRC (PATTERN (insn))) == REG)
  25454. +         {
  25455. +           if (REGNO (SET_DEST (PATTERN (insn))) < FIRST_PSEUDO_REGISTER
  25456. +               && REGNO (SET_SRC (PATTERN (insn))) >= FIRST_PSEUDO_REGISTER
  25457. +               && reg_equiv_mem[REGNO (SET_SRC (PATTERN (insn)))]
  25458. +               && reg_renumber[REGNO (SET_SRC (PATTERN (insn)))] < 0
  25459. +               && RTX_IS_SPILL_P (reg_equiv_mem[REGNO (SET_SRC (PATTERN (insn)))])
  25460. +               && !RTX_IS_SPILL_P (insn))
  25461. +             {
  25462. +               RTX_IS_SPILL_P (insn) = 1;
  25463. +               SPILL_PSEUDO (insn) = REGNO (SET_SRC (PATTERN (insn)));
  25464. +             }
  25465. +           if (REGNO (SET_DEST (PATTERN (insn))) >= FIRST_PSEUDO_REGISTER
  25466. +               && REGNO (SET_SRC (PATTERN (insn))) < FIRST_PSEUDO_REGISTER
  25467. +               && reg_equiv_mem[REGNO (SET_DEST (PATTERN (insn)))]
  25468. +               && reg_renumber[REGNO (SET_DEST (PATTERN (insn)))] < 0
  25469. +               && RTX_IS_SPILL_P (reg_equiv_mem[REGNO (SET_DEST (PATTERN (insn)))])
  25470. +               && !RTX_IS_SPILL_P (insn))
  25471. +             {
  25472. +               RTX_IS_SPILL_P (insn) = 1;
  25473. +               SPILL_PSEUDO (insn) = REGNO (SET_DEST (PATTERN (insn)));
  25474. +             }
  25475. +   if (scratch_list)
  25476. +     free (scratch_list);
  25477. +   scratch_list = 0;
  25478. +   if (scratch_block)
  25479. +     free (scratch_block);
  25480. +   scratch_block = 0;
  25481. +         }
  25482. +     }
  25483.     /* Now eliminate all pseudo regs by modifying them into
  25484.        their equivalent memory references.
  25485.        The REG-rtx's for the pseudos are modified in place,
  25486. ***************
  25487. *** 2016,2028 ****
  25488.     reg_equiv_constant = 0;
  25489.     reg_equiv_memory_loc = 0;
  25490.   
  25491. !   if (scratch_list)
  25492. !     free (scratch_list);
  25493. !   scratch_list = 0;
  25494. !   if (scratch_block)
  25495. !     free (scratch_block);
  25496. !   scratch_block = 0;
  25497.     return failure;
  25498.   }
  25499.   
  25500. --- 2090,2106 ----
  25501.     reg_equiv_constant = 0;
  25502.     reg_equiv_memory_loc = 0;
  25503.   
  25504. !   /* intel1 */
  25505. !   if (num_reload_stack_slots == MAX_RELOAD_STACK_SLOTS)
  25506. !     { /* Too many so don't use any */
  25507. !       for (insn = first; insn ; insn = next_nonnote_insn (insn))
  25508. !         {
  25509. !           if (GET_CODE (insn) == INSN )
  25510. !             {
  25511. !               RTX_IS_SPILL_P (insn) = 0;
  25512. !             }
  25513. !         }
  25514. !     }
  25515.     return failure;
  25516.   }
  25517.   
  25518. ***************
  25519. *** 2325,2330 ****
  25520. --- 2403,2417 ----
  25521.     REGNO (regno_reg_rtx[i])
  25522.       = reg_renumber[i] >= 0 ? reg_renumber[i] : i;
  25523.   
  25524. +   /* intel1 */
  25525. +   if (reg_renumber[i] < 0 
  25526. +       && reg_equiv_memory_loc[i] != 0
  25527. +       && is_a_param_slot (reg_equiv_memory_loc[i]))
  25528. +     {
  25529. +       pseudo_spilled[i] = 1;
  25530. +       RTX_IS_SPILL_P (reg_equiv_memory_loc[i]) = 1;
  25531. +       RTX_IS_SPILL_P (XEXP (reg_equiv_memory_loc[i], 0)) = 1;
  25532. +     }
  25533.     /* If we have a pseudo that is needed but has no hard reg or equivalent,
  25534.        allocate a stack slot for it.  */
  25535.   
  25536. ***************
  25537. *** 2338,2343 ****
  25538. --- 2425,2432 ----
  25539.         int total_size = MAX (inherent_size, reg_max_ref_width[i]);
  25540.         int adjust = 0;
  25541.   
  25542. +       /* intel1 */
  25543. +       pseudo_spilled[i] = 1;
  25544.         /* Each pseudo reg has an inherent size which comes from its own mode,
  25545.        and a total size which provides room for paradoxical subregs
  25546.        which refer to the pseudo reg in wider modes.
  25547. ***************
  25548. *** 2350,2362 ****
  25549.       {
  25550.         /* No known place to spill from => no slot to reuse.  */
  25551.         x = assign_stack_local (GET_MODE (regno_reg_rtx[i]), total_size, -1);
  25552.         if (BYTES_BIG_ENDIAN)
  25553.           /* Cancel the  big-endian correction done in assign_stack_local.
  25554.              Get the address of the beginning of the slot.
  25555.              This is so we can do a big-endian correction unconditionally
  25556.              below.  */
  25557.           adjust = inherent_size - total_size;
  25558.         RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[i]);
  25559.       }
  25560.         /* Reuse a stack slot if possible.  */
  25561. --- 2439,2453 ----
  25562.       {
  25563.         /* No known place to spill from => no slot to reuse.  */
  25564.         x = assign_stack_local (GET_MODE (regno_reg_rtx[i]), total_size, -1);
  25565. +       /* intel1 */
  25566. +       RTX_IS_SPILL_P (x) = 1;
  25567. +       RTX_IS_SPILL_P (XEXP (x, 0)) = 1;
  25568.         if (BYTES_BIG_ENDIAN)
  25569.           /* Cancel the  big-endian correction done in assign_stack_local.
  25570.              Get the address of the beginning of the slot.
  25571.              This is so we can do a big-endian correction unconditionally
  25572.              below.  */
  25573.           adjust = inherent_size - total_size;
  25574.         RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[i]);
  25575.       }
  25576.         /* Reuse a stack slot if possible.  */
  25577. ***************
  25578. *** 2364,2370 ****
  25579. --- 2455,2463 ----
  25580.              && spill_stack_slot_width[from_reg] >= total_size
  25581.              && (GET_MODE_SIZE (GET_MODE (spill_stack_slot[from_reg]))
  25582.              >= inherent_size))
  25583. +         {
  25584.       x = spill_stack_slot[from_reg];
  25585. +      }
  25586.         /* Allocate a bigger slot.  */
  25587.         else
  25588.       {
  25589. ***************
  25590. *** 2383,2400 ****
  25591.         /* Make a slot with that size.  */
  25592.         x = assign_stack_local (mode, total_size, -1);
  25593.         stack_slot = x;
  25594.         if (BYTES_BIG_ENDIAN)
  25595.           {
  25596.             /* Cancel the  big-endian correction done in assign_stack_local.
  25597. !          Get the address of the beginning of the slot.
  25598. !          This is so we can do a big-endian correction unconditionally
  25599. !          below.  */
  25600.             adjust = GET_MODE_SIZE (mode) - total_size;
  25601. !           if (adjust)
  25602. !         stack_slot = gen_rtx (MEM, mode_for_size (total_size
  25603. !                               * BITS_PER_UNIT,
  25604. !                               MODE_INT, 1),
  25605. !                       plus_constant (XEXP (x, 0), adjust));
  25606.           }
  25607.         spill_stack_slot[from_reg] = stack_slot;
  25608.         spill_stack_slot_width[from_reg] = total_size;
  25609. --- 2476,2496 ----
  25610.         /* Make a slot with that size.  */
  25611.         x = assign_stack_local (mode, total_size, -1);
  25612.         stack_slot = x;
  25613. +       /* intel1 */
  25614. +       RTX_IS_SPILL_P (x) = 1;
  25615. +       RTX_IS_SPILL_P (XEXP (x, 0)) = 1;
  25616.         if (BYTES_BIG_ENDIAN)
  25617.           {
  25618.             /* Cancel the  big-endian correction done in assign_stack_local.
  25619. !              Get the address of the beginning of the slot.
  25620. !              This is so we can do a big-endian correction unconditionally
  25621. !              below.  */
  25622.             adjust = GET_MODE_SIZE (mode) - total_size;
  25623. !           if(adjust)
  25624. !             stack_slot = gen_rtx (MEM, mode_for_size (total_size
  25625. !                              * BITS_PER_UNIT,
  25626. !                              MODE_INT, 1),
  25627. !                              plus_constant (XEXP (x, 0), adjust));
  25628.           }
  25629.         spill_stack_slot[from_reg] = stack_slot;
  25630.         spill_stack_slot_width[from_reg] = total_size;
  25631. ***************
  25632. *** 2412,2417 ****
  25633. --- 2508,2516 ----
  25634.         x = gen_rtx (MEM, GET_MODE (regno_reg_rtx[i]),
  25635.                  plus_constant (XEXP (x, 0), adjust));
  25636.         RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[i]);
  25637. +       /* intel1 */
  25638. +       RTX_IS_SPILL_P (x) = 1;
  25639. +       RTX_IS_SPILL_P (XEXP (x, 0)) = 1;
  25640.       }
  25641.   
  25642.         /* Save the stack slot for later.   */
  25643. ***************
  25644. *** 2650,2655 ****
  25645. --- 2749,2756 ----
  25646.     int i, j;
  25647.     char *fmt;
  25648.     int copied = 0;
  25649. +   /* intel1 */
  25650. +   int indx;
  25651.   
  25652.     switch (code)
  25653.       {
  25654. ***************
  25655. *** 2699,2704 ****
  25656. --- 2800,2823 ----
  25657.            address in case it is shared.  */
  25658.         new = eliminate_regs (reg_equiv_memory_loc[regno],
  25659.                   mem_mode, insn);
  25660. +       /* intel1 */
  25661. +       if ((flag_loop_after_global || flag_peep_spills)
  25662. +           && treplace_insn && is_a_stack_slot (new) 
  25663. +           && !is_a_reload_stack_slot (new, &indx, cur_stack_offset, treplace_insn)
  25664. +           && num_reload_stack_slots < MAX_RELOAD_STACK_SLOTS)
  25665. +         {
  25666. +               if (num_reload_stack_slots < MAX_RELOAD_STACK_SLOTS)
  25667. +                 {
  25668. +               reload_slots[num_reload_stack_slots].cur_stack_offset 
  25669. +                 = cur_stack_offset;
  25670. +               reload_slots[num_reload_stack_slots].stack_slot_pseudo_reg 
  25671. +             = regno;
  25672. +               reload_slots[num_reload_stack_slots].reload_stack_slot 
  25673. +             = new;
  25674. +               reload_slots[num_reload_stack_slots++].reload_insn
  25675. +             = treplace_insn;
  25676. +         }
  25677. +         }
  25678.         if (new != reg_equiv_memory_loc[regno])
  25679.           {
  25680.             cannot_omit_stores[regno] = 1;
  25681. ***************
  25682. *** 3094,3103 ****
  25683. --- 3213,3226 ----
  25684.         new = eliminate_regs (XEXP (x, 0), GET_MODE (x), insn);
  25685.         if (new != XEXP (x, 0))
  25686.       {
  25687. +       /* intel1 */
  25688. +       new->is_spill_rtx = x->is_spill_rtx;
  25689.         new = gen_rtx (MEM, GET_MODE (x), new);
  25690.         new->volatil = x->volatil;
  25691.         new->unchanging = x->unchanging;
  25692.         new->in_struct = x->in_struct;
  25693. +       /* intel1 */
  25694. +       new->is_spill_rtx = x->is_spill_rtx;
  25695.         return new;
  25696.       }
  25697.         else
  25698. ***************
  25699. *** 3236,3242 ****
  25700.              will delete it in reload_as_needed once we know that this
  25701.              elimination is, in fact, being done.
  25702.   
  25703. !            If REPLACE isn't set, we can't delete this insn, but needn't
  25704.              process it since it won't be used unless something changes.  */
  25705.           if (replace)
  25706.             delete_dead_insn (insn);
  25707. --- 3359,3365 ----
  25708.              will delete it in reload_as_needed once we know that this
  25709.              elimination is, in fact, being done.
  25710.   
  25711. !            If REPLACE isn't set, we can't delete this insn, but neededn't
  25712.              process it since it won't be used unless something changes.  */
  25713.           if (replace)
  25714.             delete_dead_insn (insn);
  25715. ***************
  25716. *** 3288,3295 ****
  25717. --- 3411,3422 ----
  25718.        re-recognize the insn.  We do this in case we had a simple addition
  25719.        but now can do this as a load-address.  This saves an insn in this
  25720.        common case. */
  25721. +   /* intel1 */
  25722. +   treplace_insn = replace ? insn : NULL_RTX;
  25723.   
  25724.     new_body = eliminate_regs (old_body, 0, replace ? insn : NULL_RTX);
  25725. +   /* intel1 */
  25726. +   treplace_insn = NULL_RTX;
  25727.     if (new_body != old_body)
  25728.       {
  25729.         /* If we aren't replacing things permanently and we changed something,
  25730. ***************
  25731. *** 3806,3812 ****
  25732.       {
  25733.         rtx avoid_return_reg = 0;
  25734.         rtx oldpat = PATTERN (insn);
  25735.   #ifdef SMALL_REGISTER_CLASSES
  25736.         /* Set avoid_return_reg if this is an insn
  25737.            that might use the value of a function call.  */
  25738. --- 3933,3938 ----
  25739. ***************
  25740. *** 3961,3966 ****
  25741. --- 4087,4102 ----
  25742.             forget_old_reloads_1 (XEXP (x, 0), NULL_RTX);
  25743.             }
  25744.   #endif
  25745. +           /* intel1 */
  25746. +       if (GET_CODE (PATTERN (insn)) == PARALLEL)
  25747. +         {
  25748. +           int i;
  25749. +           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
  25750. +         update_stack_offset (XVECEXP (PATTERN (insn), 0, i), 
  25751. +                              &cur_stack_offset);
  25752. +         }
  25753. +       else
  25754. +         update_stack_offset (PATTERN (insn), &cur_stack_offset);
  25755.       }
  25756.         /* A reload reg's contents are unknown after a label.  */
  25757.         if (GET_CODE (insn) == CODE_LABEL)
  25758. ***************
  25759. *** 5650,5661 ****
  25760.     rtx output_address_reload_insns[MAX_RECOG_OPERANDS];
  25761.     rtx operand_reload_insns = 0;
  25762.     rtx other_operand_reload_insns = 0;
  25763. -   rtx other_output_reload_insns = 0;
  25764.     rtx following_insn = NEXT_INSN (insn);
  25765.     rtx before_insn = insn;
  25766.     int special;
  25767.     /* Values to be put in spill_reg_store are put here first.  */
  25768.     rtx new_spill_reg_store[FIRST_PSEUDO_REGISTER];
  25769.   
  25770.     for (j = 0; j < reload_n_operands; j++)
  25771.       input_reload_insns[j] = input_address_reload_insns[j]
  25772. --- 5786,5798 ----
  25773.     rtx output_address_reload_insns[MAX_RECOG_OPERANDS];
  25774.     rtx operand_reload_insns = 0;
  25775.     rtx other_operand_reload_insns = 0;
  25776.     rtx following_insn = NEXT_INSN (insn);
  25777.     rtx before_insn = insn;
  25778.     int special;
  25779.     /* Values to be put in spill_reg_store are put here first.  */
  25780.     rtx new_spill_reg_store[FIRST_PSEUDO_REGISTER];
  25781. +   int indx; /* intel1 */
  25782. +   rtx tmp_stack_slot, reload_insn; /* intel1 */
  25783.   
  25784.     for (j = 0; j < reload_n_operands; j++)
  25785.       input_reload_insns[j] = input_address_reload_insns[j]
  25786. ***************
  25787. *** 6054,6062 ****
  25788.                          third_reload_reg)));
  25789.                   }
  25790.                 else
  25791.                   gen_reload (second_reload_reg, oldequiv,
  25792.                       reload_opnum[j],
  25793. !                     reload_when_needed[j]);
  25794.   
  25795.                 oldequiv = second_reload_reg;
  25796.               }
  25797. --- 6191,6231 ----
  25798.                          third_reload_reg)));
  25799.                   }
  25800.                 else
  25801. +               /* intel1 */
  25802. +               reload_insn =
  25803.                   gen_reload (second_reload_reg, oldequiv,
  25804.                       reload_opnum[j],
  25805. !             reload_when_needed[j]);
  25806. !              /* intel1 */
  25807. !              if ((flag_loop_after_global ||flag_peep_spills) 
  25808. !                &&is_a_reload_stack_slot(oldequiv,&indx,cur_stack_offset,NULL))
  25809. !               {
  25810. !                  RTX_IS_SPILL_P (reload_insn) = 1;
  25811. !                  if (indx == -1)
  25812. !                  {
  25813. !                     tmp_stack_slot
  25814. !                      = eliminate_regs (
  25815. !                      reg_equiv_memory_loc[REGNO (oldequiv)],
  25816. !                      GET_MODE (oldequiv), NULL_RTX);
  25817. !                      if (num_reload_stack_slots < MAX_RELOAD_ STACK_SLOTS
  25818. !                      && !is_a_reload_stack_slot (tmp_stack_slot, &indx, cur_stack_offset, NULL))
  25819. !                      {
  25820. !                         reload_slots[num_reload_stack_slots].cur_stack_offset
  25821. !                            = cur_stack_offset;
  25822. !                       reload_slots[num_reload_stack_slots].stack_slot_pseudo_reg
  25823. !                            = REGNO (oldequiv);
  25824. !                           reload_slots[num_reload_stack_slots].reload_stack_slot
  25825. !                            = tmp_stack_slot;
  25826. !                            reload_slots[num_reload_stack_slots++].reload_insn
  25827. !                            = NULL;
  25828. !                       }
  25829. !                          SPILL_PSEUDO (reload_insn) = REGNO (oldequiv);
  25830. !                     }
  25831. !                      else
  25832. !                         SPILL_PSEUDO (reload_insn)
  25833. !                          = reload_slots[indx].stack_slot_pseudo_reg;
  25834. !                   }
  25835.   
  25836.                 oldequiv = second_reload_reg;
  25837.               }
  25838. ***************
  25839. *** 6065,6072 ****
  25840.   #endif
  25841.   
  25842.             if (! special && ! rtx_equal_p (reloadreg, oldequiv))
  25843. !         gen_reload (reloadreg, oldequiv, reload_opnum[j],
  25844.                   reload_when_needed[j]);
  25845.   
  25846.   #if defined(SECONDARY_INPUT_RELOAD_CLASS) && defined(PRESERVE_DEATH_INFO_REGNO_P)
  25847.             /* We may have to make a REG_DEAD note for the secondary reload
  25848. --- 6234,6271 ----
  25849.   #endif
  25850.   
  25851.             if (! special && ! rtx_equal_p (reloadreg, oldequiv))
  25852. !           /* intel1 */
  25853. !         reload_insn = gen_reload (reloadreg, oldequiv, reload_opnum[j],
  25854.                   reload_when_needed[j]);
  25855. +       /* intel1 */ if ((flag_loop_after_global || flag_peep_spills)
  25856. +            && is_a_reload_stack_slot (oldequiv, &indx, cur_stack_offset, NULL))
  25857. +           {
  25858. +            RTX_IS_SPILL_P (reload_insn) = 1;
  25859. +            if (indx == -1)
  25860. +              {
  25861. +                tmp_stack_slot
  25862. +                  = eliminate_regs (
  25863. +                  reg_equiv_memory_loc[REGNO (oldequiv)],
  25864. +                  GET_MODE (oldequiv), NULL_RTX);
  25865. +                   if (num_reload_stack_slots < MAX_RELOAD_STACK_SLOTS
  25866. +                      && !is_a_reload_stack_slot (tmp_stack_slot, &indx, cur_stack_offset, NULL))
  25867. +                   {
  25868. +                      reload_slots[num_reload_stack_slots].cur_stack_offset
  25869. +                       = cur_stack_offset;
  25870. +                      reload_slots[num_reload_stack_slots].stack_slot_pseudo_reg
  25871. +                       = REGNO (oldequiv);
  25872. +                        reload_slots[num_reload_stack_slots].reload_stack_slot 
  25873. +                       = tmp_stack_slot;
  25874. +                         reload_slots[num_reload_stack_slots++].reload_insn
  25875. +                       = NULL;
  25876. +                   }
  25877. +                     SPILL_PSEUDO (reload_insn) = REGNO (oldequiv);
  25878. +               }
  25879. +             else
  25880. +               SPILL_PSEUDO (reload_insn)
  25881. +                 = reload_slots[indx].stack_slot_pseudo_reg;
  25882. +           }
  25883.   
  25884.   #if defined(SECONDARY_INPUT_RELOAD_CLASS) && defined(PRESERVE_DEATH_INFO_REGNO_P)
  25885.             /* We may have to make a REG_DEAD note for the secondary reload
  25886. ***************
  25887. *** 6260,6275 ****
  25888.             XEXP (note, 0) = reload_reg_rtx[j];
  25889.             continue;
  25890.           }
  25891. -       /* Likewise for a SUBREG of an operand that dies.  */
  25892. -       else if (GET_CODE (old) == SUBREG
  25893. -            && GET_CODE (SUBREG_REG (old)) == REG
  25894. -            && 0 != (note = find_reg_note (insn, REG_UNUSED,
  25895. -                           SUBREG_REG (old))))
  25896. -         {
  25897. -           XEXP (note, 0) = gen_lowpart_common (GET_MODE (old),
  25898. -                            reload_reg_rtx[j]);
  25899. -           continue;
  25900. -         }
  25901.         else if (GET_CODE (old) == SCRATCH)
  25902.           /* If we aren't optimizing, there won't be a REG_UNUSED note,
  25903.              but we don't want to make an output reload.  */
  25904. --- 6459,6464 ----
  25905. ***************
  25906. *** 6289,6298 ****
  25907.         if (GET_CODE (insn) == JUMP_INSN)
  25908.           abort ();
  25909.   
  25910. !       if (reload_when_needed[j] == RELOAD_OTHER)
  25911. !         start_sequence ();
  25912. !       else
  25913. !         push_to_sequence (output_reload_insns[reload_opnum[j]]);
  25914.   
  25915.         /* Determine the mode to reload in.
  25916.            See comments above (for input reloading).  */
  25917. --- 6478,6484 ----
  25918.         if (GET_CODE (insn) == JUMP_INSN)
  25919.           abort ();
  25920.   
  25921. !       push_to_sequence (output_reload_insns[reload_opnum[j]]);
  25922.   
  25923.         /* Determine the mode to reload in.
  25924.            See comments above (for input reloading).  */
  25925. ***************
  25926. *** 6358,6380 ****
  25927.               {
  25928.                 rtx third_reloadreg
  25929.                   = reload_reg_rtx[reload_secondary_out_reload[secondary_reload]];
  25930. -               rtx tem;
  25931.   
  25932.                 /* Copy primary reload reg to secondary reload reg.
  25933.                    (Note that these have been swapped above, then
  25934.                    secondary reload reg to OLD using our insn.  */
  25935.   
  25936. -               /* If REAL_OLD is a paradoxical SUBREG, remove it
  25937. -                  and try to put the opposite SUBREG on
  25938. -                  RELOADREG.  */
  25939. -               if (GET_CODE (real_old) == SUBREG
  25940. -                   && (GET_MODE_SIZE (GET_MODE (real_old))
  25941. -                   > GET_MODE_SIZE (GET_MODE (SUBREG_REG (real_old))))
  25942. -                   && 0 != (tem = gen_lowpart_common
  25943. -                        (GET_MODE (SUBREG_REG (real_old)),
  25944. -                     reloadreg)))
  25945. -                 real_old = SUBREG_REG (real_old), reloadreg = tem;
  25946.                 gen_reload (reloadreg, second_reloadreg,
  25947.                         reload_opnum[j], reload_when_needed[j]);
  25948.                 emit_insn ((GEN_FCN (tertiary_icode)
  25949. --- 6544,6554 ----
  25950. ***************
  25951. *** 6392,6402 ****
  25952. --- 6566,6612 ----
  25953.           }
  25954.           }
  25955.   #endif
  25956. +     /* PROBLEM: supposed to be intel code here, but too much has
  25957. +       changed above, I don't know how it maps */
  25958.   
  25959.         /* Output the last reload insn.  */
  25960.         if (! special)
  25961. + /*
  25962.           gen_reload (old, reloadreg, reload_opnum[j],
  25963.               reload_when_needed[j]);
  25964. + */
  25965. +         {
  25966. +             emit_insn(gen_move_insn(old,reloadreg));
  25967. +  /* intel1 */ if ((flag_loop_after_global || flag_peep_spills)
  25968. +               && is_a_reload_stack_slot (old, &indx, cur_stack_offset, NULL))
  25969. +               {
  25970. +                   reload_insn = get_last_insn ();
  25971. +                   RTX_IS_SPILL_P ( reload_insn) = 1;
  25972. +                   if (indx == -1)
  25973. +                   {
  25974. +                      tmp_stack_slot = eliminate_regs (
  25975. +                             reg_equiv_memory_loc[REGNO (old)],
  25976. +                             GET_MODE (old), NULL_RTX);
  25977. +                     if (num_reload_stack_slots < MAX_RELOAD_STACK_SLOTS
  25978. +                        && !is_a_reload_stack_slot (tmp_stack_slot, &indx,
  25979. +                          cur_stack_offset, NULL))
  25980. +                     {
  25981. +                       reload_slots[num_reload_stack_slots].cur_stack_offset
  25982. +                                 = cur_stack_offset;
  25983. +                       reload_slots[num_reload_stack_slots].stack_slot_pseudo_reg
  25984. +                                 = REGNO (old);
  25985. +                       reload_slots[num_reload_stack_slots].reload_stack_slot
  25986. +                                 = tmp_stack_slot;
  25987. +                       reload_slots[num_reload_stack_slots++].reload_insn = NULL;
  25988. +                     }
  25989. +                   SPILL_PSEUDO (reload_insn) = REGNO (old);
  25990. +                  } else
  25991. +                     SPILL_PSEUDO (reload_insn)
  25992. +                          = reload_slots[indx].stack_slot_pseudo_reg;
  25993. +                }
  25994. +             }
  25995.   
  25996.   #ifdef PRESERVE_DEATH_INFO_REGNO_P
  25997.         /* If final will look at death notes for this reg,
  25998. ***************
  25999. *** 6436,6450 ****
  26000.             new_spill_reg_store[reload_spill_index[j]] = p;
  26001.             }
  26002.   
  26003. !       if (reload_when_needed[j] == RELOAD_OTHER)
  26004. !         {
  26005. !           if (other_output_reload_insns)
  26006. !         emit_insns (other_output_reload_insns);
  26007. !           other_output_reload_insns = get_insns ();
  26008. !         }
  26009. !       else
  26010. !         output_reload_insns[reload_opnum[j]] = get_insns ();
  26011.         end_sequence ();
  26012.       }
  26013.       }
  26014. --- 6646,6652 ----
  26015.             new_spill_reg_store[reload_spill_index[j]] = p;
  26016.             }
  26017.   
  26018. !       output_reload_insns[reload_opnum[j]] = get_insns ();
  26019.         end_sequence ();
  26020.       }
  26021.       }
  26022. ***************
  26023. *** 6455,6461 ****
  26024.   
  26025.        RELOAD_FOR_OTHER_ADDRESS reloads for input addresses.
  26026.   
  26027. !      RELOAD_OTHER reloads, output in ascending order by reload number.
  26028.   
  26029.        For each operand, any RELOAD_FOR_INPUT_ADDRESS reloads followed by
  26030.        the RELOAD_FOR_INPUT reload for the operand.
  26031. --- 6657,6663 ----
  26032.   
  26033.        RELOAD_FOR_OTHER_ADDRESS reloads for input addresses.
  26034.   
  26035. !      RELOAD_OTHER reloads.
  26036.   
  26037.        For each operand, any RELOAD_FOR_INPUT_ADDRESS reloads followed by
  26038.        the RELOAD_FOR_INPUT reload for the operand.
  26039. ***************
  26040. *** 6467,6476 ****
  26041.        After the insn being reloaded, we write the following:
  26042.   
  26043.        For each operand, any RELOAD_FOR_OUTPUT_ADDRESS reload followed by
  26044. !      the RELOAD_FOR_OUTPUT reload for that operand.
  26045. !      Any RELOAD_OTHER output reloads, output in descending order by
  26046. !      reload number.  */
  26047.   
  26048.     emit_insns_before (other_input_address_reload_insns, before_insn);
  26049.     emit_insns_before (other_input_reload_insns, before_insn);
  26050. --- 6669,6675 ----
  26051.        After the insn being reloaded, we write the following:
  26052.   
  26053.        For each operand, any RELOAD_FOR_OUTPUT_ADDRESS reload followed by
  26054. !      the RELOAD_FOR_OUTPUT reload for that operand.  */
  26055.   
  26056.     emit_insns_before (other_input_address_reload_insns, before_insn);
  26057.     emit_insns_before (other_input_reload_insns, before_insn);
  26058. ***************
  26059. *** 6490,6497 ****
  26060.         emit_insns_before (output_reload_insns[j], following_insn);
  26061.       }
  26062.   
  26063. -   emit_insns_before (other_output_reload_insns, following_insn);
  26064.     /* Move death notes from INSN
  26065.        to output-operand-address and output reload insns.  */
  26066.   #ifdef PRESERVE_DEATH_INFO_REGNO_P
  26067. --- 6689,6694 ----
  26068. ***************
  26069. *** 6691,6696 ****
  26070. --- 6888,6895 ----
  26071.        int opnum;
  26072.        enum reload_type type;
  26073.   {
  26074. +   /* intel1 */
  26075. +   int indx;
  26076.     rtx last = get_last_insn ();
  26077.     rtx tem;
  26078.   
  26079. ***************
  26080. *** 6858,6864 ****
  26081. --- 7057,7080 ----
  26082.   
  26083.     /* If IN is a simple operand, use gen_move_insn.  */
  26084.     else if (GET_RTX_CLASS (GET_CODE (in)) == 'o' || GET_CODE (in) == SUBREG)
  26085. +   {
  26086.       emit_insn (gen_move_insn (out, in));
  26087. +     if ((flag_loop_after_global || flag_peep_spills)   /* intel1 */
  26088. +       && is_a_reload_stack_slot (in, &indx, cur_stack_offset, get_last_insn()))
  26089. +       {
  26090. +         rtx reload_insn = get_last_insn ();
  26091. +   RTX_IS_SPILL_P ( reload_insn) = 1;
  26092. +   if (indx == -1)
  26093. +      {
  26094. +            SPILL_PSEUDO (reload_insn) = REGNO (in);
  26095. +      }
  26096. +   else
  26097. +      SPILL_PSEUDO (reload_insn)
  26098. +         = reload_slots[indx].stack_slot_pseudo_reg;
  26099. +       }
  26100. +   }
  26101.   
  26102.   #ifdef HAVE_reload_load_address
  26103.     else if (HAVE_reload_load_address)
  26104. ***************
  26105. *** 7173,7176 ****
  26106. --- 7389,7643 ----
  26107.       }
  26108.       }
  26109.     return count;
  26110. + }
  26111. + /* intel1 */
  26112. + /* return 1 if rx is a stack slot */
  26113. + int
  26114. + is_a_stack_slot (rx)
  26115. +   rtx rx;
  26116. + {
  26117. +  if (GET_CODE (rx) != MEM)
  26118. +     {
  26119. +       return (0);
  26120. +     }
  26121. +   if (GET_CODE (XEXP (rx, 0)) == PLUS 
  26122. +       && XEXP ( XEXP (rx, 0), 0) == stack_pointer_rtx 
  26123. +       && !frame_pointer_needed)
  26124. +     {
  26125. +       if ( GET_CODE (XEXP ( XEXP (rx, 0), 1)) == CONST_INT)
  26126. +         {
  26127. +           return (1);
  26128. +         }
  26129. +       else
  26130. +         {
  26131. +           return (0);
  26132. +         }
  26133. +     }
  26134. +   else if (GET_CODE (XEXP (rx, 0)) == PLUS 
  26135. +       && XEXP ( XEXP (rx, 0), 0) == frame_pointer_rtx
  26136. +       && frame_pointer_needed)
  26137. +     {
  26138. +       if ( GET_CODE (XEXP ( XEXP (rx, 0), 1)) == CONST_INT)
  26139. +         {
  26140. +           return (1);
  26141. +         }
  26142. +       else
  26143. +         {
  26144. +           return (0);
  26145. +         }
  26146. +     }
  26147. +   else if ((XEXP (rx, 0) == frame_pointer_rtx  && frame_pointer_needed)
  26148. +            || (XEXP (rx, 0) == stack_pointer_rtx && ! frame_pointer_needed))
  26149. +     {
  26150. +       return (1);
  26151. +     }
  26152. +   else
  26153. +     {
  26154. +       return (0);
  26155. +     }
  26156. +    
  26157. + }
  26158. + /*
  26159. +   if rx is a reload slot then set *indx to the index in the
  26160. +     reload_slots array which contains it and return 1
  26161. +   else
  26162. +     return 0
  26163. + */
  26164. + int
  26165. + is_a_reload_stack_slot (rx, indx, cur_stack_offset, reload_insn)
  26166. +      rtx rx;
  26167. +      int *indx;
  26168. +      int cur_stack_offset;
  26169. +      rtx reload_insn;
  26170. + {
  26171. +   int i, is_based_on_stack_pointer, stack_offset, stack_i_offset;
  26172. +   rtx stack_slot_i;
  26173. +   
  26174. +   if (GET_CODE (rx) == REG && REGNO (rx) >= FIRST_PSEUDO_REGISTER
  26175. +       && pseudo_spilled[REGNO (rx)])
  26176. +     {
  26177. +       *indx = -1;
  26178. +       return (1);
  26179. +     }
  26180. +   if (GET_CODE (rx) == SUBREG 
  26181. +       && GET_CODE (SUBREG_REG (rx)) == MEM)
  26182. +     {
  26183. +       return (is_a_reload_stack_slot (SUBREG_REG (rx), indx, 
  26184. +                                       cur_stack_offset, reload_insn));
  26185. +     }
  26186. +   if (GET_CODE (rx) != MEM)
  26187. +     {
  26188. +       return (0);
  26189. +     }
  26190. +   is_based_on_stack_pointer = 0;
  26191. +   if (GET_CODE (XEXP (rx, 0)) == PLUS 
  26192. +       && XEXP ( XEXP (rx, 0), 0) == stack_pointer_rtx 
  26193. +       && !frame_pointer_needed)
  26194. +     {
  26195. +       is_based_on_stack_pointer = 1;
  26196. +       if ( GET_CODE (XEXP ( XEXP (rx, 0), 1)) == CONST_INT)
  26197. +         {
  26198. +           stack_offset = XINT (XEXP ( XEXP (rx, 0), 1), 0);
  26199. +         }
  26200. +       else
  26201. +         {
  26202. +           return (0);
  26203. +         }
  26204. +     }
  26205. +   else if (GET_CODE (XEXP (rx, 0)) == PLUS 
  26206. +       && XEXP ( XEXP (rx, 0), 0) == frame_pointer_rtx
  26207. +       && frame_pointer_needed)
  26208. +     {
  26209. +       if ( GET_CODE (XEXP ( XEXP (rx, 0), 1)) == CONST_INT)
  26210. +         {
  26211. +           ;
  26212. +         }
  26213. +       else
  26214. +         {
  26215. +           return (0);
  26216. +         }
  26217. +     }
  26218. +   else if ((XEXP (rx, 0) == frame_pointer_rtx  && frame_pointer_needed)
  26219. +            || (XEXP (rx, 0) == stack_pointer_rtx && ! frame_pointer_needed))
  26220. +     {
  26221. +       is_based_on_stack_pointer = (XEXP (rx, 0) == stack_pointer_rtx );
  26222. +     }
  26223. +   else
  26224. +     {
  26225. +       return (0);
  26226. +     }
  26227. +            
  26228. +   for (i = 0; i < num_reload_stack_slots; i++)
  26229. +     {
  26230. +       if (!is_based_on_stack_pointer)
  26231. +         {
  26232. +           if ((reload_insn == NULL || reload_insn == reload_slots[i].reload_insn)
  26233. +               && rtx_equal_p (XEXP (reload_slots[i].reload_stack_slot, 0), 
  26234. +                            XEXP (rx, 0)))
  26235. +         {
  26236. +           *indx = i;
  26237. +           return (1);
  26238. +         }
  26239. +     }
  26240. +       else
  26241. +         {
  26242. +           stack_slot_i = XEXP (reload_slots[i].reload_stack_slot, 0);
  26243. +           if (GET_CODE (stack_slot_i) == PLUS 
  26244. +               && XEXP ( stack_slot_i, 0) == stack_pointer_rtx)
  26245. +             {
  26246. +               if ( GET_CODE (XEXP ( stack_slot_i, 1)) == CONST_INT)
  26247. +                 {
  26248. +                   stack_i_offset = XINT (XEXP ( stack_slot_i, 1), 0);
  26249. +                 }
  26250. +               else
  26251. +                 {
  26252. +                   abort ();
  26253. +                 }
  26254. +             }
  26255. +           else if (stack_slot_i == stack_pointer_rtx)
  26256. +             {
  26257. +               stack_i_offset = 0;
  26258. +             }
  26259. +           else
  26260. +             {
  26261. +               abort ();
  26262. +             }
  26263. +           stack_i_offset -= reload_slots[i].cur_stack_offset;
  26264. +           if ((reload_insn == NULL || reload_insn == reload_slots[i].reload_insn)
  26265. +               && (stack_offset - cur_stack_offset == stack_i_offset))
  26266. +             {
  26267. +           *indx = i;
  26268. +           return (1);
  26269. +             }
  26270. +         }
  26271. +     }
  26272. +   return (0);
  26273. + }
  26274. + int
  26275. + are_same_reload_slots (slot1, offset1, slot2, offset2)
  26276. +   rtx slot1, slot2;
  26277. +   int offset1, offset2;
  26278. + {
  26279. +   rtx base_reg1, base_reg2;
  26280. +   int add_val1, add_val2;
  26281. +   if (GET_CODE (XEXP (slot1, 0)) == PLUS)
  26282. +     {
  26283. +       if (GET_CODE (XEXP (XEXP (slot1, 0), 0)) == REG)
  26284. +         {
  26285. +           base_reg1 = XEXP (XEXP (slot1, 0), 0);
  26286. +           if (GET_CODE (XEXP (XEXP (slot1, 0), 1)) == CONST_INT)
  26287. +             {
  26288. +               add_val1 = XINT (XEXP (XEXP (slot1, 0), 1), 0);
  26289. +             }
  26290. +         }
  26291. +     }
  26292. +   else
  26293. +     {
  26294. +       add_val1 = 0;
  26295. +       base_reg1 = XEXP (slot1, 0);
  26296. +     }
  26297. +     
  26298. +   if (GET_CODE (XEXP (slot2, 0)) == PLUS)
  26299. +     {
  26300. +       if (GET_CODE (XEXP (XEXP (slot2, 0), 0)) == REG)
  26301. +         {
  26302. +           base_reg2 = XEXP (XEXP (slot2, 0), 0);
  26303. +           if (GET_CODE (XEXP (XEXP (slot2, 0), 1)) == CONST_INT)
  26304. +             {
  26305. +               add_val2 = XINT (XEXP (XEXP (slot2, 0), 1), 0);
  26306. +             }
  26307. +         }
  26308. +     }
  26309. +   else
  26310. +     {
  26311. +       add_val2 = 0;
  26312. +       base_reg2 = XEXP (slot2, 0);
  26313. +     }
  26314. +   if (base_reg1 == frame_pointer_rtx)
  26315. +     {
  26316. +       offset1 = 0;
  26317. +     }
  26318. +   if (base_reg2 == frame_pointer_rtx)
  26319. +     {
  26320. +       offset2 = 0;
  26321. +     }
  26322. +   if (base_reg1 == base_reg2 
  26323. +       && ((add_val1 - offset1) == (add_val2 - offset2)))
  26324. +     {
  26325. +       return (1);
  26326. +     }
  26327. +   return (0);
  26328. + }
  26329. + /*
  26330. +   if x refernces a paramater then return 1
  26331. +   else return 0
  26332. + */
  26333. + int 
  26334. + is_a_param_slot (x)
  26335. +      rtx x;
  26336. + {
  26337. +   if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == PLUS
  26338. +       && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
  26339. +       && REGNO (XEXP (XEXP (x, 0), 0)) == ARG_POINTER_REGNUM
  26340. +       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
  26341. +     {
  26342. +       return (1);
  26343. +     }
  26344. +   if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == REG
  26345. +       && REGNO (XEXP (x, 0)) == ARG_POINTER_REGNUM)
  26346. +     {
  26347. +       return (1);
  26348. +     }
  26349. +   return (0);
  26350.   }
  26351. diff -rNci gcc-2.7.2/reorg.c gcc-2.7.2p/reorg.c
  26352. *** gcc-2.7.2/reorg.c    Fri Sep 15 21:38:55 1995
  26353. --- gcc-2.7.2p/reorg.c    Thu Jun 15 12:02:32 1995
  26354. ***************
  26355. *** 2857,2880 ****
  26356.         && eligible_for_delay (insn, slots_filled, trial, flags)
  26357.         && no_labels_between_p (insn, trial))
  26358.       {
  26359. -       rtx *tmp;
  26360.         slots_filled++;
  26361.         delay_list = add_to_delay_list (trial, delay_list);
  26362. -       /* TRIAL may have had its delay slot filled, then unfilled.  When
  26363. -          the delay slot is unfilled, TRIAL is placed back on the unfilled
  26364. -          slots obstack.  Unfortunately, it is placed on the end of the
  26365. -          obstack, not in its original location.  Therefore, we must search
  26366. -          from entry i + 1 to the end of the unfilled slots obstack to
  26367. -          try and find TRIAL.  */
  26368. -       tmp = &unfilled_slots_base[i + 1];
  26369. -       while (*tmp != trial && tmp != unfilled_slots_next)
  26370. -         tmp++;
  26371.         /* Remove the unconditional jump from consideration for delay slot
  26372. !          filling and unthread it.   */
  26373. !       if (*tmp == trial)
  26374. !         *tmp = 0;
  26375.         {
  26376.           rtx next = NEXT_INSN (trial);
  26377.           rtx prev = PREV_INSN (trial);
  26378. --- 2857,2868 ----
  26379.         && eligible_for_delay (insn, slots_filled, trial, flags)
  26380.         && no_labels_between_p (insn, trial))
  26381.       {
  26382.         slots_filled++;
  26383.         delay_list = add_to_delay_list (trial, delay_list);
  26384.         /* Remove the unconditional jump from consideration for delay slot
  26385. !          filling and unthread it.  */
  26386. !       if (unfilled_slots_base[i + 1] == trial)
  26387. !         unfilled_slots_base[i + 1] = 0;
  26388.         {
  26389.           rtx next = NEXT_INSN (trial);
  26390.           rtx prev = PREV_INSN (trial);
  26391. ***************
  26392. *** 2974,2985 ****
  26393.        is a CALL_INSN (or a CALL_INSN is passed), cannot trap (because the
  26394.        call might not return).
  26395.   
  26396. !      There used to be code which continued past the target label if
  26397. !      we saw all uses of the target label.  This code did not work,
  26398. !      because it failed to account for some instructions which were
  26399. !      both annulled and marked as from the target.  This can happen as a
  26400. !      result of optimize_skip.  Since this code was redundant with
  26401. !      fill_eager_delay_slots anyways, it was just deleted.  */
  26402.   
  26403.         if (slots_filled != slots_to_fill
  26404.             && (GET_CODE (insn) != JUMP_INSN
  26405. --- 2962,2975 ----
  26406.        is a CALL_INSN (or a CALL_INSN is passed), cannot trap (because the
  26407.        call might not return).
  26408.   
  26409. !      If this is a conditional jump, see if it merges back to us early
  26410. !      enough for us to pick up insns from the merge point.  Don't do
  26411. !      this if there is another branch to our label unless we pass all of
  26412. !      them.
  26413. !      Another similar merge is if we jump to the same place that a
  26414. !      later unconditional jump branches to.  In that case, we don't
  26415. !      care about the number of uses of our label.  */
  26416.   
  26417.         if (slots_filled != slots_to_fill
  26418.             && (GET_CODE (insn) != JUMP_INSN
  26419. ***************
  26420. *** 2989,2994 ****
  26421. --- 2979,2986 ----
  26422.       {
  26423.         rtx target = 0;
  26424.         int maybe_never = 0;
  26425. +       int passed_label = 0;
  26426. +       int target_uses;
  26427.         struct resources needed_at_jump;
  26428.   
  26429.         CLEAR_RESOURCE (&needed);
  26430. ***************
  26431. *** 3005,3011 ****
  26432.             mark_set_resources (insn, &set, 0, 1);
  26433.             mark_referenced_resources (insn, &needed, 1);
  26434.             if (GET_CODE (insn) == JUMP_INSN)
  26435. !         target = JUMP_LABEL (insn);
  26436.           }
  26437.   
  26438.         for (trial = next_nonnote_insn (insn); trial; trial = next_trial)
  26439. --- 2997,3009 ----
  26440.             mark_set_resources (insn, &set, 0, 1);
  26441.             mark_referenced_resources (insn, &needed, 1);
  26442.             if (GET_CODE (insn) == JUMP_INSN)
  26443. !         {
  26444. !           /* Get our target and show how many more uses we want to
  26445. !              see before we hit the label.  */
  26446. !           target = JUMP_LABEL (insn);
  26447. !           target_uses = LABEL_NUSES (target) - 1;
  26448. !         }
  26449. !         
  26450.           }
  26451.   
  26452.         for (trial = next_nonnote_insn (insn); trial; trial = next_trial)
  26453. ***************
  26454. *** 3014,3021 ****
  26455.   
  26456.             next_trial = next_nonnote_insn (trial);
  26457.   
  26458. !           if (GET_CODE (trial) == CODE_LABEL
  26459. !           || GET_CODE (trial) == BARRIER)
  26460.           break;
  26461.   
  26462.             /* We must have an INSN, JUMP_INSN, or CALL_INSN.  */
  26463. --- 3012,3033 ----
  26464.   
  26465.             next_trial = next_nonnote_insn (trial);
  26466.   
  26467. !           if (GET_CODE (trial) == CODE_LABEL)
  26468. !         {
  26469. !           passed_label = 1;
  26470. !           /* If this is our target, see if we have seen all its uses.
  26471. !              If so, indicate we have passed our target and ignore it.
  26472. !              All other labels cause us to stop our search.  */
  26473. !           if (trial == target && target_uses == 0)
  26474. !             {
  26475. !               target = 0;
  26476. !               continue;
  26477. !             }
  26478. !           else
  26479. !             break;
  26480. !         }
  26481. !           else if (GET_CODE (trial) == BARRIER)
  26482.           break;
  26483.   
  26484.             /* We must have an INSN, JUMP_INSN, or CALL_INSN.  */
  26485. ***************
  26486. *** 3040,3046 ****
  26487.           {
  26488.             if (target == 0)
  26489.               break;
  26490. !           else if (JUMP_LABEL (trial_delay) != target)
  26491.               {
  26492.                 mark_target_live_regs
  26493.               (next_active_insn (JUMP_LABEL (trial_delay)),
  26494. --- 3052,3060 ----
  26495.           {
  26496.             if (target == 0)
  26497.               break;
  26498. !           else if (JUMP_LABEL (trial_delay) == target)
  26499. !             target_uses--;
  26500. !           else
  26501.               {
  26502.                 mark_target_live_regs
  26503.               (next_active_insn (JUMP_LABEL (trial_delay)),
  26504. ***************
  26505. *** 3073,3078 ****
  26506. --- 3087,3094 ----
  26507.               link_cc0_insns (trial);
  26508.   #endif
  26509.   
  26510. +           if (passed_label)
  26511. +             update_block (trial, trial);
  26512.             delete_insn (trial);
  26513.             if (slots_to_fill == ++slots_filled)
  26514.               break;
  26515. ***************
  26516. *** 3398,3405 ****
  26517.             trial = try_split (pat, trial, 0);
  26518.             if (new_thread == old_trial)
  26519.           new_thread = trial;
  26520. -           if (thread == old_trial)
  26521. -         thread = trial;
  26522.             pat = PATTERN (trial);
  26523.             if ((thread_if_true
  26524.              ? eligible_for_annul_false (insn, *pslots_filled, trial, flags)
  26525. --- 3414,3419 ----
  26526. ***************
  26527. *** 3663,3669 ****
  26528.         if (condition == 0)
  26529.       continue;
  26530.   
  26531. !       /* Get the next active fallthrough and target insns and see if we own
  26532.        them.  Then see whether the branch is likely true.  We don't need
  26533.        to do a lot of this for unconditional branches.  */
  26534.   
  26535. --- 3677,3683 ----
  26536.         if (condition == 0)
  26537.       continue;
  26538.   
  26539. !       /* Get the next active fallthough and target insns and see if we own
  26540.        them.  Then see whether the branch is likely true.  We don't need
  26541.        to do a lot of this for unconditional branches.  */
  26542.   
  26543. diff -rNci gcc-2.7.2/rtl.c gcc-2.7.2p/rtl.c
  26544. *** gcc-2.7.2/rtl.c    Thu Jun 15 12:02:59 1995
  26545. --- gcc-2.7.2p/rtl.c    Tue Jan 23 09:25:31 1996
  26546. ***************
  26547. *** 174,184 ****
  26548.                  "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
  26549.                  "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG"};
  26550.   
  26551.   char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
  26552.                 "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
  26553.                 "REG_NONNEG", "REG_NO_CONFLICT", "REG_UNUSED",
  26554.                 "REG_CC_SETTER", "REG_CC_USER", "REG_LABEL",
  26555. !               "REG_DEP_ANTI", "REG_DEP_OUTPUT" };
  26556.   
  26557.   /* Allocate an rtx vector of N elements.
  26558.      Store the length, and initialize all elements to zero.  */
  26559. --- 174,185 ----
  26560.                  "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
  26561.                  "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG"};
  26562.   
  26563. + /* intel1 added REG_DEP_TMP */
  26564.   char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
  26565.                 "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
  26566.                 "REG_NONNEG", "REG_NO_CONFLICT", "REG_UNUSED",
  26567.                 "REG_CC_SETTER", "REG_CC_USER", "REG_LABEL",
  26568. !               "REG_DEP_ANTI", "REG_DEP_OUTPUT", "REG_DEP_TMP"  };
  26569.   
  26570.   /* Allocate an rtx vector of N elements.
  26571.      Store the length, and initialize all elements to zero.  */
  26572. ***************
  26573. *** 302,307 ****
  26574. --- 303,310 ----
  26575.     copy->volatil = orig->volatil;
  26576.     copy->unchanging = orig->unchanging;
  26577.     copy->integrated = orig->integrated;
  26578. +   /* intel1 */
  26579. +   copy->is_spill_rtx = orig->is_spill_rtx;
  26580.     
  26581.     format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
  26582.   
  26583. diff -rNci gcc-2.7.2/rtl.def gcc-2.7.2p/rtl.def
  26584. *** gcc-2.7.2/rtl.def    Thu Jun 15 12:03:32 1995
  26585. --- gcc-2.7.2p/rtl.def    Tue Jan 23 09:25:31 1996
  26586. ***************
  26587. *** 347,353 ****
  26588.      ---------------------------------------------------------------------- */
  26589.   
  26590.   /* An instruction that cannot jump.  */
  26591. ! DEF_RTL_EXPR(INSN, "insn", "iuueiee", 'i')
  26592.   
  26593.   /* An instruction that can possibly jump.
  26594.      Fields ( rtx->fld[] ) have exact same meaning as INSN's.  */
  26595. --- 347,354 ----
  26596.      ---------------------------------------------------------------------- */
  26597.   
  26598.   /* An instruction that cannot jump.  */
  26599. ! /* intel1 added last 0 - this field is used in scheduling */
  26600. ! DEF_RTL_EXPR(INSN, "insn", "iuueiee0", 'i')
  26601.   
  26602.   /* An instruction that can possibly jump.
  26603.      Fields ( rtx->fld[] ) have exact same meaning as INSN's.  */
  26604. ***************
  26605. *** 644,650 ****
  26606.   
  26607.   /* Operand:
  26608.        0:  value to be shifted.
  26609. !      1:  number of bits.  */
  26610.   DEF_RTL_EXPR(ASHIFT, "ashift", "ee", '2')
  26611.   DEF_RTL_EXPR(ROTATE, "rotate", "ee", '2')
  26612.   
  26613. --- 645,655 ----
  26614.   
  26615.   /* Operand:
  26616.        0:  value to be shifted.
  26617. !      1:  number of bits.  
  26618. !    ASHIFT and LSHIFT are distinguished because on some machines
  26619. !    these allow a negative operand and shift right in that case.
  26620. ! */
  26621. ! DEF_RTL_EXPR(LSHIFT, "lshift", "ee", '2')
  26622.   DEF_RTL_EXPR(ASHIFT, "ashift", "ee", '2')
  26623.   DEF_RTL_EXPR(ROTATE, "rotate", "ee", '2')
  26624.   
  26625. diff -rNci gcc-2.7.2/rtl.h gcc-2.7.2p/rtl.h
  26626. *** gcc-2.7.2/rtl.h    Thu Jun 15 12:03:16 1995
  26627. --- gcc-2.7.2p/rtl.h    Tue Jan 23 09:25:31 1996
  26628. ***************
  26629. *** 140,145 ****
  26630. --- 140,148 ----
  26631.        In a REG, nonzero means this reg refers to the return value
  26632.        of the current function.  */
  26633.     unsigned integrated : 1;
  26634. +   /* intel1 Nonzero if this rtx is a spill rtx */
  26635. +   /* intel2 overlap: Nonzero if this rtx was created by memory_simplify */
  26636. +   unsigned is_spill_rtx: 1;
  26637.     /* The first element of the operands of this rtx.
  26638.        The number of operands and their types are controlled
  26639.        by the `code' field, according to rtl.def.  */
  26640. ***************
  26641. *** 211,216 ****
  26642. --- 214,223 ----
  26643.   
  26644.   #define RTX_INTEGRATED_P(RTX) ((RTX)->integrated)
  26645.   #define RTX_UNCHANGING_P(RTX) ((RTX)->unchanging)
  26646. + /* intel1 */
  26647. + #define RTX_IS_SPILL_P(RTX) ((RTX)->is_spill_rtx)
  26648. + /* intel2 - see a note above (for is_spill_rtx field) */
  26649. + #define RTX_IS_RISC_P(RTX) ((RTX)->is_spill_rtx)
  26650.   
  26651.   /* RTL vector.  These appear inside RTX's when there is a need
  26652.      for a variable number of things.  The principle use is inside
  26653. ***************
  26654. *** 259,264 ****
  26655. --- 266,276 ----
  26656.   #define PREV_INSN(INSN)    ((INSN)->fld[1].rtx)
  26657.   #define NEXT_INSN(INSN)    ((INSN)->fld[2].rtx)
  26658.   
  26659. + /* intel1 used in sched*/
  26660. + #define ORG_NEXT_INSN(INSN)    ((INSN)->fld[7].rtx)
  26661. + /* intel1 used in (loop) opt of spills */
  26662. + #define SPILL_PSEUDO(INSN)    ((INSN)->fld[7].rtint)
  26663.   /* The body of an insn.  */
  26664.   #define PATTERN(INSN)    ((INSN)->fld[3].rtx)
  26665.   
  26666. ***************
  26667. *** 348,354 ****
  26668.           REG_EQUAL = 5, REG_RETVAL = 6, REG_LIBCALL = 7,
  26669.           REG_NONNEG = 8, REG_NO_CONFLICT = 9, REG_UNUSED = 10,
  26670.           REG_CC_SETTER = 11, REG_CC_USER = 12, REG_LABEL = 13,
  26671. !         REG_DEP_ANTI = 14, REG_DEP_OUTPUT = 15 };
  26672.   
  26673.   /* Define macros to extract and insert the reg-note kind in an EXPR_LIST.  */
  26674.   #define REG_NOTE_KIND(LINK) ((enum reg_note) GET_MODE (LINK))
  26675. --- 360,366 ----
  26676.           REG_EQUAL = 5, REG_RETVAL = 6, REG_LIBCALL = 7,
  26677.           REG_NONNEG = 8, REG_NO_CONFLICT = 9, REG_UNUSED = 10,
  26678.           REG_CC_SETTER = 11, REG_CC_USER = 12, REG_LABEL = 13,
  26679. !         REG_DEP_ANTI = 14, REG_DEP_OUTPUT = 15, REG_DEP_TMP = 16 };
  26680.   
  26681.   /* Define macros to extract and insert the reg-note kind in an EXPR_LIST.  */
  26682.   #define REG_NOTE_KIND(LINK) ((enum reg_note) GET_MODE (LINK))
  26683. diff -rNci gcc-2.7.2/rtlanal.c gcc-2.7.2p/rtlanal.c
  26684. *** gcc-2.7.2/rtlanal.c    Fri Oct  6 17:13:57 1995
  26685. --- gcc-2.7.2p/rtlanal.c    Thu Jun 15 12:03:58 1995
  26686. ***************
  26687. *** 428,435 ****
  26688.   static rtx reg_set_reg;
  26689.   static int reg_set_flag;
  26690.   
  26691. ! static void
  26692. ! reg_set_p_1 (x, pat)
  26693.        rtx x;
  26694.   {
  26695.     /* We don't want to return 1 if X is a MEM that contains a register
  26696. --- 428,435 ----
  26697.   static rtx reg_set_reg;
  26698.   static int reg_set_flag;
  26699.   
  26700. ! void
  26701. ! reg_set_p_1 (x)
  26702.        rtx x;
  26703.   {
  26704.     /* We don't want to return 1 if X is a MEM that contains a register
  26705. ***************
  26706. *** 905,911 ****
  26707.           || ((GET_CODE (reg_set_last_value) == REG
  26708.                || GET_CODE (reg_set_last_value) == SUBREG)
  26709.               && ! reg_set_between_p (reg_set_last_value,
  26710. !                         insn, orig_insn)))
  26711.             return reg_set_last_value;
  26712.           else
  26713.             return 0;
  26714. --- 905,911 ----
  26715.           || ((GET_CODE (reg_set_last_value) == REG
  26716.                || GET_CODE (reg_set_last_value) == SUBREG)
  26717.               && ! reg_set_between_p (reg_set_last_value,
  26718. !                         NEXT_INSN (insn), orig_insn)))
  26719.             return reg_set_last_value;
  26720.           else
  26721.             return 0;
  26722. diff -rNci gcc-2.7.2/scan-decls.c gcc-2.7.2p/scan-decls.c
  26723. *** gcc-2.7.2/scan-decls.c    Mon Jun 19 18:18:43 1995
  26724. --- gcc-2.7.2p/scan-decls.c    Thu Jun 15 12:04:57 1995
  26725. ***************
  26726. *** 246,252 ****
  26727.         break;
  26728.   
  26729.        default:
  26730. !       prev_id_start = 0;
  26731.       }
  26732.       }
  26733.   }
  26734. --- 246,252 ----
  26735.         break;
  26736.   
  26737.        default:
  26738. !       prev_id_start = NULL;
  26739.       }
  26740.       }
  26741.   }
  26742. diff -rNci gcc-2.7.2/sched.c gcc-2.7.2p/sched.c
  26743. *** gcc-2.7.2/sched.c    Thu Jun 15 12:06:39 1995
  26744. --- gcc-2.7.2p/sched.c    Tue Jan 30 21:06:34 1996
  26745. ***************
  26746. *** 125,131 ****
  26747. --- 125,153 ----
  26748.   #include "insn-config.h"
  26749.   #include "insn-attr.h"
  26750.   
  26751. + /* intel1 */
  26752. + #ifndef STACK_PUSH_CODE
  26753. + #ifdef STACK_GROWS_DOWNWARD
  26754. + #define STACK_PUSH_CODE PRE_DEC
  26755. + #else
  26756. + #define STACK_PUSH_CODE PRE_INC
  26757. + #endif
  26758. + #endif
  26759.   #ifdef INSN_SCHEDULING
  26760. + /* intel1 */
  26761. + #ifndef STACK_PUSH_CODE
  26762. + #ifdef STACK_GROWS_DOWNWARD
  26763. + #define STACK_PUSH_CODE PRE_DEC
  26764. + #else
  26765. + #define STACK_PUSH_CODE PRE_INC
  26766. + #endif
  26767. + #endif
  26768. + #ifdef SMALL_REGISTER_CLASSES
  26769. +   /* can't move anything past a hard register */
  26770. + static rtx first_insn_to_pivot;
  26771. + static rtx last_hard_reg_insn;
  26772. + #endif
  26773.   /* Arrays set up by scheduling for the same respective purposes as
  26774.      similar-named arrays set up by flow analysis.  We work with these
  26775.      arrays during the scheduling pass so we can compare values against
  26776. ***************
  26777. *** 146,151 ****
  26778. --- 168,184 ----
  26779.   static regset reg_pending_sets;
  26780.   static int reg_pending_sets_all;
  26781.   
  26782. + /* intel1 */
  26783. + #ifdef NO_STACK_REG_REORDER
  26784. + /* don't reorder insns that refernce stack registers */
  26785. + static rtx prev_stack_reg_insn = NULL;
  26786. + #endif
  26787. + /* intel1 */
  26788. + #ifdef STACK_REGS
  26789. + static int maintain_order = 0;
  26790. + #endif
  26791. + static FILE * cur_dump_file;
  26792.   /* Vector indexed by INSN_UID giving the original ordering of the insns.  */
  26793.   static int *insn_luid;
  26794.   #define INSN_LUID(INSN) (insn_luid[INSN_UID (INSN)])
  26795. ***************
  26796. *** 293,305 ****
  26797.   };
  26798.   
  26799.   /* Forward declarations.  */
  26800.   static rtx canon_rtx            PROTO((rtx));
  26801.   static int rtx_equal_for_memref_p    PROTO((rtx, rtx));
  26802.   static rtx find_symbolic_term        PROTO((rtx));
  26803.   static int memrefs_conflict_p        PROTO((int, rtx, int, rtx,
  26804.                              HOST_WIDE_INT));
  26805.   static void add_dependence        PROTO((rtx, rtx, enum reg_note));
  26806. ! static void remove_dependence        PROTO((rtx, rtx));
  26807.   static rtx find_insn_list        PROTO((rtx, rtx));
  26808.   static int insn_unit            PROTO((rtx));
  26809.   static unsigned int blockage_range    PROTO((int, rtx));
  26810. --- 326,342 ----
  26811.   };
  26812.   
  26813.   /* Forward declarations.  */
  26814. + /* intel1 */
  26815. + static int is_part_of_group            PROTO((rtx, rtx));
  26816. + static int prev_insts_in_block        PROTO((int, rtx));
  26817.   static rtx canon_rtx            PROTO((rtx));
  26818.   static int rtx_equal_for_memref_p    PROTO((rtx, rtx));
  26819.   static rtx find_symbolic_term        PROTO((rtx));
  26820.   static int memrefs_conflict_p        PROTO((int, rtx, int, rtx,
  26821.                              HOST_WIDE_INT));
  26822.   static void add_dependence        PROTO((rtx, rtx, enum reg_note));
  26823. ! void remove_dependence        PROTO((rtx, rtx));
  26824.   static rtx find_insn_list        PROTO((rtx, rtx));
  26825.   static int insn_unit            PROTO((rtx));
  26826.   static unsigned int blockage_range    PROTO((int, rtx));
  26827. ***************
  26828. *** 629,634 ****
  26829. --- 666,906 ----
  26830.     else
  26831.       y = canon_rtx (y);
  26832.   
  26833. +   /* intel1
  26834. +      Missing special handling of a push onto the stack.  */
  26835. +   if (reload_completed
  26836. +       &&
  26837. +       (GET_CODE (x) == STACK_PUSH_CODE
  26838. +        && XEXP (x, 0) == stack_pointer_rtx)
  26839. +       ||
  26840. +       (GET_CODE (y) == STACK_PUSH_CODE
  26841. +        && XEXP (y, 0) == stack_pointer_rtx)
  26842. +       )
  26843. +     {
  26844. +       rtx *push, *non_push;
  26845. +       if (GET_CODE (x) == STACK_PUSH_CODE
  26846. +           && XEXP (x, 0) == stack_pointer_rtx)
  26847. +         {
  26848. +           push = &x;
  26849. +           non_push = &y;
  26850. +         }
  26851. +       else
  26852. +         {
  26853. +           push = &y;
  26854. +           non_push = &x;
  26855. +         }
  26856. +       if (find_symbolic_term (*non_push) != NULL)
  26857. +         {  /* push onto stack does not conflict with global */
  26858. +           return (0);
  26859. +         }
  26860. +       if (RTX_IS_SPILL_P (*non_push))
  26861. +         { /* push onto stack does not overlap with spill slot */
  26862. +           return (0);
  26863. +         }
  26864. +       /* Check to see if the non push is a stack slot */
  26865. +       if (c == 0 && GET_CODE (*non_push) == PLUS 
  26866. +           && XEXP ( *non_push, 0) == stack_pointer_rtx 
  26867. +           && !frame_pointer_needed)
  26868. +         {
  26869. +           if ( GET_CODE (XEXP ( *non_push, 1)) == CONST_INT
  26870. +                && XINT (XEXP (*non_push, 1), 0) 
  26871. +                   > GET_MODE_SIZE (GET_MODE (*push)))
  26872. +             {
  26873. +               return (0);
  26874. +             }
  26875. +         }
  26876. +       else if (c == 0 && GET_CODE (*non_push) == PLUS 
  26877. +           && XEXP ( *non_push, 0) == frame_pointer_rtx
  26878. +           && frame_pointer_needed)
  26879. +         {
  26880. +           if ( GET_CODE (XEXP ( *non_push, 1)) == CONST_INT)
  26881. +             {
  26882. +               return (0); /* Definitely not the same as the push if
  26883. +                              frame_pointer is used.  */
  26884. +             }
  26885. +         }
  26886. +     }
  26887. +   
  26888. +   
  26889. +   /* intel1
  26890. +      Missing handling of a spill slot - can't conflict with anything
  26891. +      that is not a spill slot */
  26892. +   if (reload_completed && RTX_IS_SPILL_P (x) != RTX_IS_SPILL_P (y)
  26893. +       && !rtx_equal_p(x,y) /*just to be safe */)
  26894. +     { /* Actually some spill slots are not being marked at present -
  26895. +          but no non spill slots are ever marked.  So make sure
  26896. +          that the non spill slot does not overlap with spill slot */
  26897. +       rtx *spill, *non_spill;
  26898. +       int *spill_size, *non_spill_size, spill_offset, non_spill_offset, 
  26899. +           spill_unknown, non_spill_unknown, maybe_spill;
  26900. +       spill_unknown = 0;
  26901. +       non_spill_unknown = 0;
  26902. +       maybe_spill = 0;
  26903. +       if (RTX_IS_SPILL_P (x))
  26904. +         {
  26905. +           spill = &x;
  26906. +           spill_size = &xsize;
  26907. +           non_spill = &y;
  26908. +           non_spill_size = &ysize;
  26909. +         }
  26910. +       else
  26911. +         {
  26912. +           spill = &y;
  26913. +           spill_size = &ysize;
  26914. +           non_spill = &x;
  26915. +           non_spill_size = &xsize;
  26916. +         }
  26917. +       if (GET_CODE (*non_spill) == PLUS)
  26918. +         {
  26919. +           if (GET_CODE (XEXP (*non_spill, 1)) == CONST_INT)
  26920. +             {
  26921. +               non_spill_offset = XINT (XEXP (*non_spill, 1), 0);
  26922. +             }
  26923. +           else
  26924. +             {
  26925. +               non_spill_unknown = 1;
  26926. +             }
  26927. +           if (GET_CODE (XEXP (*non_spill, 0)) == REG
  26928. +               && ((frame_pointer_needed && XEXP (*non_spill, 0) == frame_pointer_rtx)
  26929. +                   || XEXP (*non_spill, 0) == stack_pointer_rtx))
  26930. +             {
  26931. +               maybe_spill = 1; /* It may overlap the spill slot */
  26932. +             }
  26933. +         }
  26934. +       else
  26935. +       if (GET_CODE (*non_spill) == REG
  26936. +           && ((frame_pointer_needed && *non_spill == frame_pointer_rtx)
  26937. +               || *non_spill == stack_pointer_rtx))
  26938. +         {
  26939. +           non_spill_offset = 0;
  26940. +           maybe_spill = 1;
  26941. +         }
  26942. +       if (maybe_spill == 0)
  26943. +         return (0);
  26944. +         
  26945. +       if (GET_CODE (*spill) == PLUS)
  26946. +         {
  26947. +           if (GET_CODE (XEXP (*spill, 1)) == CONST_INT)
  26948. +             {
  26949. +               spill_offset = XINT (XEXP (*spill, 1), 0);
  26950. +             }
  26951. +           else
  26952. +             {
  26953. +               spill_unknown = 1;
  26954. +             }
  26955. +           if (GET_CODE (XEXP (*spill, 0)) == REG
  26956. +               && ((frame_pointer_needed && XEXP (*spill, 0) == frame_pointer_rtx)
  26957. +                   || XEXP (*spill, 0) == stack_pointer_rtx))
  26958. +             {
  26959. +               ; /* ok */
  26960. +             }
  26961. +           else
  26962. +             {
  26963. +               spill_unknown = 1;
  26964. +             }
  26965. +         }
  26966. +       else
  26967. +       if (GET_CODE (*spill) == REG
  26968. +           && ((frame_pointer_needed && *spill == frame_pointer_rtx)
  26969. +               || *spill == stack_pointer_rtx))
  26970. +         {
  26971. +          spill_offset = 0;
  26972. +         }
  26973. +       else
  26974. +         {
  26975. +           spill_unknown = 1;
  26976. +         }
  26977. +       if (non_spill_unknown == 0  && spill_unknown == 0)
  26978. +         {
  26979. +           if (non_spill_offset < spill_offset)
  26980. +             return (!(non_spill_offset + *non_spill_size <= spill_offset));
  26981. +           else
  26982. +             return (!(spill_offset + *spill_size <= non_spill_offset));
  26983. +         } 
  26984. +     }
  26985. +   
  26986. +   /* intel1
  26987. +      Missing handling two spill slots conflict only if they overlap */
  26988. +   if (reload_completed && RTX_IS_SPILL_P (y) && RTX_IS_SPILL_P (x) 
  26989. +       && c == 0 
  26990. +       && !rtx_equal_p(y, x))
  26991. +     {
  26992. +       int x_offset, y_offset, x_unknown, y_unknown;
  26993. +       x_unknown = y_unknown = 0;
  26994. +       if (GET_CODE (x) == PLUS)
  26995. +         {
  26996. +           if (GET_CODE (XEXP (x, 1)) == CONST_INT)
  26997. +             {
  26998. +               x_offset = XINT (XEXP (x, 1), 0);
  26999. +             }
  27000. +           else
  27001. +             {
  27002. +               x_unknown = 1;
  27003. +             }
  27004. +           if (GET_CODE (XEXP (x, 0)) == REG
  27005. +               && ((frame_pointer_needed && XEXP (x, 0) == frame_pointer_rtx)
  27006. +                   || XEXP (x, 0) == stack_pointer_rtx))
  27007. +             {
  27008. +               ; /* ok */
  27009. +             }
  27010. +           else
  27011. +             {
  27012. +               x_unknown = 1;
  27013. +             }
  27014. +         }
  27015. +       else
  27016. +       if (GET_CODE (x) == REG
  27017. +           && ((frame_pointer_needed && x == frame_pointer_rtx)
  27018. +               || x == stack_pointer_rtx))
  27019. +         {
  27020. +          x_offset = 0;
  27021. +         }
  27022. +       else
  27023. +         {
  27024. +           x_unknown = 1;
  27025. +         }
  27026. +       if (GET_CODE (y) == PLUS)
  27027. +         {
  27028. +           if (GET_CODE (XEXP (y, 1)) == CONST_INT)
  27029. +             {
  27030. +               y_offset = XINT (XEXP (y, 1), 0);
  27031. +             }
  27032. +           else
  27033. +             {
  27034. +               y_unknown = 1;
  27035. +             }
  27036. +           if (GET_CODE (XEXP (y, 0)) == REG
  27037. +               && ((frame_pointer_needed && XEXP (y, 0) == frame_pointer_rtx)
  27038. +                   || XEXP (y, 0) == stack_pointer_rtx))
  27039. +             {
  27040. +               ; /* ok */
  27041. +             }
  27042. +           else
  27043. +             {
  27044. +               y_unknown = 1;
  27045. +             }
  27046. +         }
  27047. +       else
  27048. +       if (GET_CODE (y) == REG
  27049. +           && ((frame_pointer_needed && y == frame_pointer_rtx)
  27050. +               || y == stack_pointer_rtx))
  27051. +         {
  27052. +          y_offset = 0;
  27053. +         }
  27054. +       else
  27055. +         {
  27056. +           y_unknown = 1;
  27057. +         }
  27058. +       if (x_unknown == 0  && y_unknown == 0)
  27059. +         {
  27060. +           if (x_offset < y_offset)
  27061. +             return (!(x_offset + xsize <= y_offset));
  27062. +           else
  27063. +             return (!(y_offset + ysize <= x_offset));
  27064. +         } 
  27065. +     }
  27066. +   
  27067.     if (rtx_equal_for_memref_p (x, y))
  27068.       return (xsize == 0 || ysize == 0 ||
  27069.           (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
  27070. ***************
  27071. *** 922,928 ****
  27072. --- 1194,1208 ----
  27073.        SCHED_GROUP_P.  */
  27074.         while (NEXT_INSN (next) && SCHED_GROUP_P (NEXT_INSN (next))
  27075.            && GET_CODE (NEXT_INSN (next)) != CODE_LABEL)
  27076. +       {
  27077. +         /* intel1 - next might already be part of this SCHED_GROUP,
  27078. +         */
  27079. +         if(next==insn )
  27080. +         {
  27081. +       return;
  27082. +         }
  27083.       next = NEXT_INSN (next);
  27084. +       }
  27085.   
  27086.         /* Again, don't depend an insn on itself.  */
  27087.         if (insn == next)
  27088. ***************
  27089. *** 956,962 ****
  27090.   /* Remove ELEM wrapped in an INSN_LIST from the LOG_LINKS
  27091.      of INSN.  Abort if not found.  */
  27092.   
  27093. ! static void
  27094.   remove_dependence (insn, elem)
  27095.        rtx insn;
  27096.        rtx elem;
  27097. --- 1236,1242 ----
  27098.   /* Remove ELEM wrapped in an INSN_LIST from the LOG_LINKS
  27099.      of INSN.  Abort if not found.  */
  27100.   
  27101. ! void
  27102.   remove_dependence (insn, elem)
  27103.        rtx insn;
  27104.        rtx elem;
  27105. ***************
  27106. *** 1217,1225 ****
  27107. --- 1497,1518 ----
  27108.         if (function_units[unit].blockage_range_function)
  27109.       {
  27110.         if (function_units[unit].blockage_function)
  27111. +         {
  27112. +         /* intel1 */
  27113. + #ifdef ADJUST_BLOCKAGE
  27114. +             {
  27115. +               int blockage = (function_units[unit].blockage_function
  27116. +                (insn, unit_last_insn[instance]));
  27117. +           ADJUST_BLOCKAGE (unit_last_insn[instance], insn, blockage);
  27118. +           tick +=  blockage 
  27119. +                - function_units[unit].max_blockage;
  27120. +         }
  27121. + #else
  27122.           tick += (function_units[unit].blockage_function
  27123.                (insn, unit_last_insn[instance])
  27124.                - function_units[unit].max_blockage);
  27125. + #endif
  27126. +         }
  27127.         else
  27128.           tick += ((int) MAX_BLOCKAGE_COST (blockage_range (unit, insn))
  27129.                - function_units[unit].max_blockage);
  27130. ***************
  27131. *** 1706,1711 ****
  27132. --- 1999,2031 ----
  27133.           /* Function calls clobber all call_used regs.  */
  27134.           add_dependence (insn, last_function_call, REG_DEP_ANTI);
  27135.           }
  27136. + #ifdef SMALL_REGISTER_CLASSES
  27137. + /* intel1 
  27138. +    lifetime of hard registers must not be changed so this
  27139. +    insn becomes a pivot in the block.
  27140. + */
  27141. +           if(reload_completed==0 && regno!=STACK_POINTER_REGNUM
  27142. +              && regno!=FRAME_POINTER_REGNUM)
  27143. +             {
  27144. +               rtx tinsn;
  27145. +               tinsn = first_insn_to_pivot;
  27146. +               while(tinsn!=insn)
  27147. +                 {
  27148. +                   if(GET_CODE(tinsn)==INSN || GET_CODE(tinsn)==CALL_INSN)
  27149. +                   {
  27150. +                     add_dependence (insn,tinsn,0);
  27151. +                   }
  27152. +                   tinsn = NEXT_INSN(tinsn);
  27153. +                 }
  27154. +               if(last_hard_reg_insn)
  27155. +                 {
  27156. +                   add_dependence (insn,last_hard_reg_insn,0);
  27157. +                 }
  27158. +               first_insn_to_pivot = insn; 
  27159. +               last_hard_reg_insn = insn;
  27160. +             }
  27161. + #endif
  27162.       }
  27163.         else
  27164.       {
  27165. ***************
  27166. *** 1806,1811 ****
  27167. --- 2126,2151 ----
  27168.     if (x == 0)
  27169.       return;
  27170.   
  27171. + /* intel1 */
  27172. + #ifdef STACK_REGS
  27173. + #ifdef IS_STACK_MODE
  27174. + #ifdef NO_STACK_REG_REORDER
  27175. +   if (NO_STACK_REG_REORDER)
  27176. +     {
  27177. +       if (prev_stack_reg_insn!=NULL && insn!=prev_stack_reg_insn
  27178. +          && IS_STACK_MODE (GET_MODE (x)))
  27179. +         {
  27180. +         add_dependence (insn, prev_stack_reg_insn, REG_DEP_TMP);
  27181. +         }
  27182. +       if (IS_STACK_MODE (GET_MODE (x)))
  27183. +         {
  27184. +           prev_stack_reg_insn = insn;
  27185. +         }
  27186. +     }
  27187. + #endif
  27188. + #endif
  27189. + #endif
  27190.     code = GET_CODE (x);
  27191.   
  27192.     switch (code)
  27193. ***************
  27194. *** 1871,1876 ****
  27195. --- 2211,2243 ----
  27196.             /* Function calls clobber all call_used regs.  */
  27197.             add_dependence (insn, last_function_call, REG_DEP_ANTI);
  27198.             }
  27199. + #ifdef SMALL_REGISTER_CLASSES
  27200. + /* intel1 
  27201. +    lifetime of hard registers must not be changed so this
  27202. +    insn becomes a pivot in the block.
  27203. + */
  27204. +             if(reload_completed==0 && regno!=STACK_POINTER_REGNUM
  27205. +              && regno!=FRAME_POINTER_REGNUM)
  27206. +               {
  27207. +                 rtx tinsn;
  27208. +   
  27209. +                 tinsn = first_insn_to_pivot;
  27210. +                 while(tinsn!=insn)
  27211. +                   {
  27212. +                     if(GET_CODE(tinsn)==INSN || GET_CODE(tinsn)==CALL_INSN)
  27213. +                     {
  27214. +                       add_dependence (insn,tinsn,0);
  27215. +                     }
  27216. +                     tinsn = NEXT_INSN(tinsn);
  27217. +                   }
  27218. +                 if(last_hard_reg_insn)
  27219. +                   {
  27220. +                     add_dependence (insn,last_hard_reg_insn,0);
  27221. +                   }
  27222. +                 first_insn_to_pivot = insn; 
  27223. +                 last_hard_reg_insn = insn;
  27224. +               }
  27225. + #endif
  27226.         }
  27227.       else
  27228.         {
  27229. ***************
  27230. *** 2023,2028 ****
  27231. --- 2390,2403 ----
  27232.     int maxreg = max_reg_num ();
  27233.     int i;
  27234.   
  27235. + #ifdef SMALL_REGISTER_CLASSES
  27236. + /* intel1 */
  27237. +   if (reload_completed==0 && last_hard_reg_insn!=NULL)
  27238. +     {
  27239. +       add_dependence (insn,last_hard_reg_insn,0);
  27240. +     }
  27241. + #endif
  27242.     if (code == SET || code == CLOBBER)
  27243.       sched_analyze_1 (x, insn);
  27244.     else if (code == PARALLEL)
  27245. ***************
  27246. *** 2170,2175 ****
  27247. --- 2545,2571 ----
  27248.     register int luid = 0;
  27249.     rtx loop_notes = 0;
  27250.   
  27251. + /* intel1 */
  27252. +   rtx pinsn;
  27253. + #ifdef STACK_REGS
  27254. +   pinsn = NULL;
  27255. +   if (maintain_order && reload_completed==0)
  27256. +     { /* A block we don't want to change order but keep track of
  27257. +          register life information.  */
  27258. +       for (insn = head; insn != tail; insn = NEXT_INSN (insn))
  27259. +         {
  27260. +           if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
  27261. +             {
  27262. +               if (pinsn)
  27263. +                 {
  27264. +                   add_dependence (insn, pinsn, REG_DEP_TMP);
  27265. +                 }
  27266. +               pinsn = insn;
  27267. +             }
  27268. +         }
  27269. +     }
  27270. + #endif
  27271.     for (insn = head; ; insn = NEXT_INSN (insn))
  27272.       {
  27273.         INSN_LUID (insn) = luid++;
  27274. ***************
  27275. *** 2514,2519 ****
  27276. --- 2910,2931 ----
  27277.         rtx note;
  27278.         int n_deaths = 0;
  27279.   
  27280. +       /* intel1 */
  27281. + #ifdef STACK_REGS
  27282. + #ifdef IS_STACK_MODE
  27283. + #ifdef STACK_REG_REORDER
  27284. +       /* For stack registers don't take lifetimes into account */
  27285. +       if (birthing_insn_p (PATTERN (prev)) && STACK_REG_REORDER && 0)
  27286. +     {
  27287. +       if (GET_CODE (prev) == INSN && GET_CODE (PATTERN (prev)) == SET
  27288. +           && IS_STACK_MODE (GET_MODE (SET_DEST (PATTERN (prev)))))
  27289. +         {
  27290. +           return;
  27291. +         }
  27292. +     }
  27293. + #endif
  27294. + #endif
  27295. + #endif
  27296.         /* ??? This code has no effect, because REG_DEAD notes are removed
  27297.        before we ever get here.  */
  27298.         for (note = REG_NOTES (prev); note; note = XEXP (note, 1))
  27299. ***************
  27300. *** 2724,2730 ****
  27301.   
  27302.     if (dead_notes == 0)
  27303.       {
  27304. ! #if 1
  27305.         abort ();
  27306.   #else
  27307.         link = rtx_alloc (EXPR_LIST);
  27308. --- 3136,3143 ----
  27309.   
  27310.     if (dead_notes == 0)
  27311.       {
  27312. ! /* Sorry for this hack */
  27313. ! #if 0
  27314.         abort ();
  27315.   #else
  27316.         link = rtx_alloc (EXPR_LIST);
  27317. ***************
  27318. *** 3169,3178 ****
  27319. --- 3582,3625 ----
  27320.     register struct sometimes *regs_sometimes_live;
  27321.     int sometimes_max;
  27322.   
  27323. +   /* intel1 */
  27324. + #ifdef HAVE_cc0
  27325. +   rtx prev_to_cc0_setter;
  27326. + #endif
  27327. + #ifdef AGI
  27328. +   int possible_agi = 0;
  27329. + #endif
  27330. + #ifdef NO_STACK_REG_REORDER
  27331. +   rtx tinsn, tlink, tprev_link;
  27332. + #endif /* NO_STACK_REG_REORDER */
  27333.     if (file)
  27334.       fprintf (file, ";;\t -- basic block number %d from %d to %d --\n",
  27335.            b, INSN_UID (basic_block_head[b]), INSN_UID (basic_block_end[b]));
  27336.   
  27337. + /* intel1 */
  27338. + #ifdef NO_STACK_REG_REORDER
  27339. +   prev_stack_reg_insn = NULL;
  27340. + #endif
  27341. + #ifdef STACK_REGS
  27342. +   maintain_order = 0;
  27343. +   if (STACK_NON_STACK_INTERLEAVE || STACK_REG_REORDER)
  27344. +     {
  27345. +       rtx tinsn = head;
  27346. +       int found_stack_mode = 0;
  27347. +       while (tinsn && !found_stack_mode && tinsn != tail)
  27348. +         {
  27349. +           if (GET_CODE (tinsn) == INSN && GET_CODE (PATTERN (tinsn)) == SET
  27350. +               && IS_STACK_MODE (GET_MODE (SET_DEST (PATTERN (tinsn)))))
  27351. +             {
  27352. +               found_stack_mode = 1;
  27353. +             }
  27354. +           tinsn = next_nonnote_insn (tinsn);
  27355. +         }
  27356. +       maintain_order = !found_stack_mode;
  27357. +     }
  27358. + #endif
  27359.     i = max_reg_num ();
  27360.     reg_last_uses = (rtx *) alloca (i * sizeof (rtx));
  27361.     bzero ((char *) reg_last_uses, i * sizeof (rtx));
  27362. ***************
  27363. *** 3264,3269 ****
  27364. --- 3711,3721 ----
  27365.   
  27366.     LOG_LINKS (sched_before_next_call) = 0;
  27367.   
  27368. + #ifdef SMALL_REGISTER_CLASSES
  27369. + /* intel1 */
  27370. +   first_insn_to_pivot = head;
  27371. +   last_hard_reg_insn = NULL;
  27372. + #endif
  27373.     n_insns += sched_analyze (head, tail);
  27374.     if (n_insns == 0)
  27375.       {
  27376. ***************
  27377. *** 3280,3285 ****
  27378. --- 3732,3823 ----
  27379.     /* TAIL is now the last of the insns to be rearranged.
  27380.        Put those insns into the READY vector.  */
  27381.     insn = tail;
  27382. + /* intel1 */
  27383. + #ifdef HAVE_cc0
  27384. +   /* intel1 further if we have done compare elimination then the
  27385. +      insn before the compare should not be moved */
  27386. +   if (head!=tail 
  27387. +      && GET_CODE (basic_block_end[b])==JUMP_INSN 
  27388. +      && GET_CODE (PATTERN (basic_block_end[b]))!=PARALLEL 
  27389. +      && GET_CODE (PATTERN (basic_block_end[b]))!=ADDR_VEC 
  27390. +      && GET_CODE (XEXP (SET_SRC (PATTERN (basic_block_end[b])),0))==NE 
  27391. +      && GET_CODE (PREV_INSN (basic_block_end[b]))==INSN 
  27392. +      && GET_CODE (PATTERN (PREV_INSN (basic_block_end[b])))==SET 
  27393. +      && SET_DEST (PATTERN (PREV_INSN (basic_block_end[b])))==cc0_rtx 
  27394. +      && GET_CODE (SET_SRC (PATTERN (PREV_INSN (basic_block_end[b]))))==COMPARE 
  27395. +      && XEXP (SET_SRC (PATTERN (PREV_INSN (basic_block_end[b]))),1)==const0_rtx)
  27396. +     {
  27397. +       prev_to_cc0_setter = 
  27398. +         prev_nonnote_insn( PREV_INSN (basic_block_end[b]));
  27399. +       if (! (prev_to_cc0_setter && RTX_IS_RISC_P (prev_to_cc0_setter))
  27400. +          && prev_insts_in_block (b,PREV_INSN (basic_block_end[b])) 
  27401. +          && (head != PREV_INSN (basic_block_end[b])) )
  27402. +         {
  27403. +           SCHED_GROUP_P (PREV_INSN (basic_block_end[b]))=1;
  27404. +           /* Also must remove the 
  27405. +              prev_nonnote_insn(PREV_INSN(basic_block_end[b]) from the
  27406. +              dependency chain of both basic_block_end[b] and
  27407. +              PREV_INSN(basic_block_end[b]), to ensure that it doesn't
  27408. +              go through the ready list also */
  27409. +           if(prev_to_cc0_setter 
  27410. +              && (GET_CODE (prev_to_cc0_setter)==INSN 
  27411. +                  || GET_CODE (prev_to_cc0_setter)==CALL_INSN )
  27412. +          && ! RTX_IS_RISC_P (prev_to_cc0_setter))  /* intel2 */
  27413. +             {
  27414. +           if (find_insn_list (prev_to_cc0_setter, 
  27415. +                               LOG_LINKS (PREV_INSN (basic_block_end[b]))))
  27416. +             remove_dependence (PREV_INSN (basic_block_end[b]), 
  27417. +                                prev_to_cc0_setter);
  27418. +           if (find_insn_list (prev_to_cc0_setter, 
  27419. +                               LOG_LINKS ( basic_block_end[b])))
  27420. +             remove_dependence (basic_block_end[b], 
  27421. +                                prev_to_cc0_setter);
  27422. +         }
  27423. +         }
  27424. +       else
  27425. +         SCHED_GROUP_P(PREV_INSN(basic_block_end[b]))=0;
  27426. +     } 
  27427. +   else
  27428. +   if (head!=tail 
  27429. +      && GET_CODE (basic_block_end[b])==JUMP_INSN 
  27430. +      && GET_CODE (PATTERN (basic_block_end[b]))!=PARALLEL 
  27431. +      && GET_CODE (PATTERN (basic_block_end[b]))!=ADDR_VEC 
  27432. +      && GET_CODE (PREV_INSN (basic_block_end[b]))==INSN 
  27433. +      && GET_CODE (PATTERN (PREV_INSN (basic_block_end[b])))==SET 
  27434. +      && SET_DEST (PATTERN (PREV_INSN (basic_block_end[b])))==cc0_rtx 
  27435. +      && GET_CODE (SET_SRC (PATTERN (PREV_INSN (basic_block_end[b]))))!=COMPARE)
  27436. +     {
  27437. +       prev_to_cc0_setter = 
  27438. +         prev_nonnote_insn( PREV_INSN (basic_block_end[b]));
  27439. +       if (! (prev_to_cc0_setter && RTX_IS_RISC_P (prev_to_cc0_setter))
  27440. +          && prev_insts_in_block (b,PREV_INSN (basic_block_end[b])) 
  27441. +          && (head != PREV_INSN (basic_block_end[b])) )
  27442. +         {
  27443. +           SCHED_GROUP_P (PREV_INSN (basic_block_end[b]))=1;
  27444. +           /* Also must remove the 
  27445. +              prev_nonnote_insn(PREV_INSN(basic_block_end[b]) from the
  27446. +              dependency chain of both basic_block_end[b] and
  27447. +              PREV_INSN(basic_block_end[b]), to ensure that it doesn't
  27448. +              go through the ready list also */
  27449. +           if(prev_to_cc0_setter 
  27450. +              && (GET_CODE (prev_to_cc0_setter) == INSN 
  27451. +                  || GET_CODE (prev_to_cc0_setter) == CALL_INSN )
  27452. +          && ! RTX_IS_RISC_P (prev_to_cc0_setter))  /* intel2 */
  27453. +             {
  27454. +           if (find_insn_list (prev_to_cc0_setter, 
  27455. +                               LOG_LINKS (PREV_INSN (basic_block_end[b]))))
  27456. +             remove_dependence (PREV_INSN (basic_block_end[b]), 
  27457. +                                prev_to_cc0_setter);
  27458. +           if (find_insn_list (prev_to_cc0_setter, 
  27459. +                               LOG_LINKS ( basic_block_end[b])))
  27460. +             remove_dependence (basic_block_end[b], 
  27461. +                                prev_to_cc0_setter);
  27462. +         }
  27463. +         }
  27464. +       else
  27465. +         SCHED_GROUP_P(PREV_INSN(basic_block_end[b]))=0;
  27466. +     } 
  27467. + #endif
  27468.   
  27469.     /* For all branches, calls, uses, and cc0 setters, force them to remain
  27470.        in order at the end of the block by adding dependencies and giving
  27471. ***************
  27472. *** 3697,3710 ****
  27473.           for (; insn; insn = NEXT_INSN (insn))
  27474.             {
  27475.               if (file)
  27476. !               fprintf (file, ";; launching %d before %d with %d stalls at T-%d\n",
  27477. !                    INSN_UID (insn), INSN_UID (last), stalls, clock);
  27478.               ready[new_ready++] = insn;
  27479.               q_size -= 1;
  27480.             }
  27481.           insn_queue[NEXT_Q_AFTER (q_ptr, stalls)] = 0;
  27482.           break;
  27483.             }
  27484.   
  27485.         q_ptr = NEXT_Q_AFTER (q_ptr, stalls); clock += stalls;
  27486.       }
  27487. --- 4235,4253 ----
  27488.           for (; insn; insn = NEXT_INSN (insn))
  27489.             {
  27490.               if (file)
  27491. !               fprintf (file, ";; launching %d before %d with %d stalls at T-%d i_q[%d]\n",
  27492. !                    INSN_UID (insn), INSN_UID (last), stalls, clock, new_ready);
  27493.               ready[new_ready++] = insn;
  27494.               q_size -= 1;
  27495.             }
  27496.           insn_queue[NEXT_Q_AFTER (q_ptr, stalls)] = 0;
  27497.           break;
  27498.             }
  27499. +          /* intel1 */
  27500. + #ifdef AGI
  27501. +           if (new_ready == 1)
  27502. +             possible_agi = 1;
  27503. + #endif
  27504.   
  27505.         q_ptr = NEXT_Q_AFTER (q_ptr, stalls); clock += stalls;
  27506.       }
  27507. ***************
  27508. *** 3715,3721 ****
  27509.   
  27510.         if (file)
  27511.       {
  27512. !       fprintf (file, ";; ready list at T-%d:", clock);
  27513.         for (i = 0; i < new_ready; i++)
  27514.           fprintf (file, " %d (%x)",
  27515.                INSN_UID (ready[i]), INSN_PRIORITY (ready[i]));
  27516. --- 4258,4265 ----
  27517.   
  27518.         if (file)
  27519.       {
  27520. !       fprintf (file, ";; ready list at T-%d (new_r %d n_r %d):", 
  27521. !       clock, new_ready, n_ready);
  27522.         for (i = 0; i < new_ready; i++)
  27523.           fprintf (file, " %d (%x)",
  27524.                INSN_UID (ready[i]), INSN_PRIORITY (ready[i]));
  27525. ***************
  27526. *** 3934,3939 ****
  27527. --- 4478,4498 ----
  27528.             INSN_PRIORITY (insn) = DONE_PRIORITY;
  27529.           }
  27530.       }
  27531. + #ifdef AGI
  27532. +       if (possible_agi && reload_completed && flag_swap_for_agi)
  27533. +         {
  27534. +           rtx next_to_last = NEXT_INSN (last);    
  27535. +           if (try_eliminate_agi (last, file))
  27536. +             { /* last has been swapped downwards */
  27537. +               if (PREV_INSN (last) == tail)
  27538. +                 { /* last has moved down to become tail */
  27539. +                   tail = last;
  27540. +                 }
  27541. +               last = next_to_last;
  27542. +               insn = last;
  27543. +             }
  27544. +         }
  27545. + #endif
  27546.       }
  27547.     if (q_size != 0)
  27548.       abort ();
  27549. ***************
  27550. *** 3946,3951 ****
  27551. --- 4505,4538 ----
  27552.        TAIL is the last of those insns.  */
  27553.     head = insn;
  27554.   
  27555. + /* intel1 */
  27556. + #ifdef NO_STACK_REG_REORDER
  27557. +   if (NO_STACK_REG_REORDER)
  27558. +     { /* remove all the REG_DEP_TMP dependencies that were added */
  27559. +       for (tinsn = head; tinsn != NEXT_INSN (tail); tinsn = NEXT_INSN (tinsn))
  27560. +         {
  27561. +       tlink = LOG_LINKS (tinsn); 
  27562. +       tprev_link = tlink;
  27563. +       while (tlink) 
  27564. +         {
  27565. +           if (REG_NOTE_KIND (tlink) == REG_DEP_TMP)
  27566. +             {
  27567. +               if (tlink == LOG_LINKS (tinsn))
  27568. +                 {
  27569. +                   LOG_LINKS (tinsn) = XEXP (tlink, 1);
  27570. +                 }
  27571. +               else
  27572. +                 {
  27573. +                   XEXP (tprev_link, 1) = XEXP (tlink, 1);
  27574. +                 }
  27575. +             }
  27576. +           tprev_link = tlink;
  27577. +           tlink = XEXP (tlink, 1);
  27578. +         }
  27579. +         }
  27580. +     }
  27581. + #endif /* NO_STACK_REG_REORDER */
  27582.     /* NOTE_LIST is the end of a chain of notes previously found
  27583.        among the insns.  Insert them at the beginning of the insns.  */
  27584.     if (note_list != 0)
  27585. ***************
  27586. *** 4670,4680 ****
  27587. --- 5257,5355 ----
  27588.     int b;
  27589.     rtx insn;
  27590.   
  27591. +   cur_dump_file = dump_file;
  27592.     /* Taking care of this degenerate case makes the rest of
  27593.        this code simpler.  */
  27594.     if (n_basic_blocks == 0)
  27595.       return;
  27596.   
  27597. +   /* intel1 */
  27598. + #ifdef STACK_REGS
  27599. +   if (STACK_NON_STACK_INTERLEAVE || STACK_REG_REORDER)
  27600. +     {
  27601. +       rtx tinsn = get_insns();
  27602. +       int found_stack_mode = 0;
  27603. +       while (tinsn && !found_stack_mode)
  27604. +         {
  27605. +           if (GET_CODE (tinsn) == INSN && GET_CODE (PATTERN (tinsn)) == SET
  27606. +               && IS_STACK_MODE (GET_MODE (SET_DEST (PATTERN (tinsn)))))
  27607. +             {
  27608. +               found_stack_mode = 1;
  27609. +             }
  27610. +           tinsn = next_nonnote_insn (tinsn);
  27611. +         }
  27612. +       if (!found_stack_mode) /* Nothing to do */
  27613. +         {
  27614. +           unused_insn_list = 0;
  27615. +           unused_expr_list = 0;
  27616. +           return;
  27617. +         }
  27618. +     }
  27619. + #endif
  27620. +     /* intel1 - Remove all LOG_LINK information as the reload pass
  27621. +        may have invalidated some LOG_LINKs eg:
  27622. +        before reload:
  27623. +        (insn 21 20 24 (set (reg:SI 25)
  27624. +                (ashiftrt:SI (reg/v:SI 22)
  27625. +                    (const_int 3))) 142 {ashrsi3} (nil)
  27626. +            (nil))
  27627. +        (insn 24 21 28 (set (reg/v:SI 22)
  27628. +                (and:SI (reg/v:SI 22)
  27629. +                    (const_int 7))) 102 {andsi3} (nil)
  27630. +            (nil))
  27631. +        (insn 28 24 29 (set (reg:QI 27)
  27632. +                (and:QI (mem:QI (plus:SI (reg:SI 25)
  27633. +                            (symbol_ref:SI ("buf"))))
  27634. +                    (mem/s:QI (plus:SI (reg/v:SI 22)
  27635. +                            (symbol_ref:SI ("rmask")))))) 104 {andqi3}
  27636. +            (insn_list 21 (insn_list 24 (nil)))
  27637. +            (nil))
  27638. +        after reload:
  27639. +        (insn:HI 21 281 24 (set (reg:SI %edx)
  27640. +                (ashiftrt:SI (reg:SI %edx)
  27641. +                    (const_int 3))) 142 {ashrsi3} (nil)
  27642. +            (nil))
  27643. +        (insn 24 21 284 (set (reg/v:SI %ebp)
  27644. +                (and:SI (reg/v:SI %ebp)
  27645. +                    (const_int 7))) 102 {andsi3} (nil)
  27646. +            (nil))
  27647. +        (insn 284 24 28 (set (reg:QI %cl)
  27648. +                (mem:QI (plus:SI (reg:SI %edx)
  27649. +                        (symbol_ref:SI ("buf"))))) -1 (nil)
  27650. +            (nil))
  27651. +        (insn:HI 28 284 285 (set (reg:QI %cl)
  27652. +                (and:QI (reg:QI %cl)
  27653. +                    (mem/s:QI (plus:SI (reg/v:SI %ebp)
  27654. +                            (symbol_ref:SI ("rmask")))))) 104 {andqi3}
  27655. +            (insn_list 21 (insn_list 24 (nil)))
  27656. +             (nil))
  27657. +      Note that the LOG_LINKs of insn 28 is no longer valid - it does
  27658. +      not depend directly on insn 21 any longer. Leaving the LOG_LINKs
  27659. +      as they are may produce suboptimal, although valid, schedules.
  27660. +      */
  27661. +   if (reload_completed)
  27662. +     {
  27663. +       rtx tinsn = get_insns();
  27664. +       while (tinsn)
  27665. +         {
  27666. +           if (GET_CODE (tinsn) == INSN || GET_CODE (tinsn) == CALL_INSN
  27667. +               || GET_CODE (tinsn) == JUMP_INSN)
  27668. +             {
  27669. +               LOG_LINKS (tinsn) = NULL;
  27670. +             }
  27671. +           tinsn = next_nonnote_insn (tinsn);
  27672. +         }
  27673. +     }
  27674.     /* Create an insn here so that we can hang dependencies off of it later.  */
  27675.     sched_before_next_call
  27676.       = gen_rtx (INSN, VOIDmode, 0, NULL_RTX, NULL_RTX,
  27677. ***************
  27678. *** 4815,4820 ****
  27679. --- 5490,5497 ----
  27680.             PUT_CODE (insn, NOTE);
  27681.             NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
  27682.             NOTE_SOURCE_FILE (insn) = 0;
  27683. +           /* intel1 */
  27684. +           SCHED_GROUP_P(insn) = 0;
  27685.           }
  27686.   
  27687.             continue;
  27688. ***************
  27689. *** 4837,4842 ****
  27690. --- 5514,5521 ----
  27691.             PUT_CODE (insn, NOTE);
  27692.             NOTE_SOURCE_FILE (insn) = 0;
  27693.             NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
  27694. +           /* intel1 */
  27695. +           SCHED_GROUP_P(insn) = 0;
  27696.             if (insn == basic_block_head[b])
  27697.               basic_block_head[b] = first;
  27698.             if (insn == basic_block_end[b])
  27699. ***************
  27700. *** 4882,4887 ****
  27701. --- 5561,5568 ----
  27702.           notes++;
  27703.           NOTE_SOURCE_FILE (insn) = 0;
  27704.           NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
  27705. +         /* intel1 */
  27706. +         SCHED_GROUP_P(insn) = 0;
  27707.             }
  27708.           /* If the line number is unchanged, LINE is redundant.  */
  27709.           else if (line
  27710. ***************
  27711. *** 4965,4968 ****
  27712. --- 5646,5931 ----
  27713.         }
  27714.       }
  27715.   }
  27716. + /* intel1
  27717. +    return 1 if insn_b is part of the SCHED_GROUP of insn_a 
  27718. + */
  27719. + static int
  27720. + is_part_of_group (insn_a, insn_b)
  27721. +      rtx insn_a;
  27722. +      rtx insn_b;
  27723. + {
  27724. +   rtx pn;
  27725. +   pn = PREV_INSN(insn_a);
  27726. +   while(pn)
  27727. +     {
  27728. +       if(GET_CODE(pn)==INSN || GET_CODE(pn)==CALL_INSN ||
  27729. +          GET_CODE(pn)==JUMP_INSN)
  27730. +         {
  27731. +           if(pn==insn_b)
  27732. +             {
  27733. +               return(1);
  27734. +             }
  27735. +           if(!SCHED_GROUP_P(pn))
  27736. +             {
  27737. +               return(0);
  27738. +             }
  27739. +         }
  27740. +       pn = PREV_INSN(pn);
  27741. +     }
  27742. +   return(0);
  27743. + }
  27744. + /* intel1 return 1 if there are insts in block b before insn */
  27745. + static int prev_insts_in_block(b, insn)
  27746. + int b;
  27747. + rtx insn;
  27748. + {
  27749. +   insn = PREV_INSN(insn);
  27750. +   while(insn && insn!=basic_block_head[b])
  27751. +     {
  27752. +       if(GET_RTX_CLASS (GET_CODE (insn)) == 'i')
  27753. +         {
  27754. +           return(1);
  27755. +         }
  27756. +       insn = PREV_INSN(insn);
  27757. +     }
  27758. +   if(insn && 
  27759. +      insn==basic_block_head[b] && GET_RTX_CLASS (GET_CODE (insn)) == 'i')
  27760. +     {
  27761. +       return(1);
  27762. +     }
  27763. +   return(0);
  27764. + }
  27765. + #ifdef AGI
  27766. + /* intel1
  27767. +   If insn updates a register by a constant and NEXT_INSN (insn) uses
  27768. +   that register as a base or index and this is the only dependence
  27769. +   between the two insns - then try to swap these two insns by replacing
  27770. +   register with (register + constant) in NEXT_INSN (insn).  
  27771. + */
  27772. + int try_eliminate_agi (insn, file)
  27773. +   rtx insn;
  27774. +   FILE * file;
  27775. + {
  27776. +   rtx next;
  27777. +   int success;
  27778. +   
  27779. +   next = NEXT_INSN (insn);
  27780. +   if (!try_swap (insn))
  27781. +     {
  27782. +       return (0);
  27783. +     }
  27784. +   /* Now swap insn with next.  */
  27785. +   PREV_INSN (NEXT_INSN (next)) = insn;
  27786. +   NEXT_INSN (insn) = NEXT_INSN (next);
  27787. +   NEXT_INSN (next) = insn;
  27788. +   PREV_INSN (insn) = next;
  27789. +   success = 1;
  27790. +   if (file)
  27791. +     {
  27792. +       fprintf (file, ";; swapped %d with %d to eliminate agi, %d is last scheduled\n",
  27793. +       INSN_UID (insn), INSN_UID (next), INSN_UID (next));
  27794. +     }
  27795. +   while (success)
  27796. +     {  /* Keep trying to swap insn downwards */
  27797. +       success = try_swap (insn);
  27798. +       if (success)
  27799. +         {
  27800. +           next = NEXT_INSN (insn);
  27801. +           if (file)
  27802. +             {
  27803. +               fprintf (file, ";;   (swapped %d with %d to eliminate agi)\n",
  27804. +               INSN_UID (insn), INSN_UID (next));
  27805. +             }
  27806. +           NEXT_INSN (PREV_INSN (insn)) = next;
  27807. +           PREV_INSN (next) = PREV_INSN (insn);
  27808. +           PREV_INSN (NEXT_INSN (next)) = insn;
  27809. +           NEXT_INSN (insn) = NEXT_INSN (next);
  27810. +           NEXT_INSN (next) = insn;
  27811. +           PREV_INSN (insn) = next;
  27812. +         }
  27813. +     }
  27814. +   return (1);
  27815. + }
  27816. + int try_swap (insn)
  27817. +   rtx insn;
  27818. + {
  27819. +   rtx next, tmp, src, dest, next_src, next_dest, reg_to_update,
  27820. +       copy_dest, copy_src;
  27821. +   int offst_update, updates_by_const, regno_updated, length, i,
  27822. +       insn_code_number, save_code;
  27823. +   char * fmt, * storage;
  27824. +   next = NEXT_INSN (insn);
  27825. +   if (GET_CODE (insn) != INSN || next == NULL || GET_CODE (next) != INSN
  27826. +       || GET_CODE (PATTERN (insn)) != SET || GET_CODE (PATTERN (next)) != SET)
  27827. +     {
  27828. +       return (0);
  27829. +     }
  27830. +   src = SET_SRC (PATTERN (insn));
  27831. +   dest = SET_DEST (PATTERN (insn));
  27832. +   next_src = SET_SRC (PATTERN (next));
  27833. +   next_dest = SET_DEST (PATTERN (next));
  27834. +   if (next_dest == cc0_rtx)
  27835. +     {
  27836. +       return (0);
  27837. +     }
  27838. +   if (rtx_equal_p (dest, next_dest))
  27839. +     {
  27840. +       return (0);
  27841. +     }
  27842. +   if (GET_CODE (next_dest) == REG)
  27843. +     {
  27844. +       if (reg_overlap_mentioned_p (next_dest, PATTERN (insn)))
  27845. +         {
  27846. +           return (0);
  27847. +         }
  27848. +     }
  27849. +   /* See if insn updates some register by a constant ammount */
  27850. +   updates_by_const = 0;
  27851. +   if (GET_CODE (dest) == REG)
  27852. +     {
  27853. +       if ((GET_CODE (src) == PLUS || GET_CODE (src) == MINUS)
  27854. +           && rtx_equal_p (XEXP (src, 0), dest) 
  27855. +           && GET_CODE (XEXP (src, 1)) == CONST_INT)
  27856. +         {
  27857. +           updates_by_const = 1;
  27858. +           offst_update 
  27859. +             = XINT (XEXP (src, 1), 0) * (GET_CODE (src) == PLUS ? 1 : -1);
  27860. +           regno_updated = REGNO (dest);
  27861. +           reg_to_update = dest;
  27862. +         }
  27863. +     }
  27864. +   if (GET_CODE (dest) == MEM && push_operand (dest, GET_MODE (dest))
  27865. +       && (GET_CODE (src) == REG
  27866. +           || (GET_CODE (src) == MEM && !side_effects_p (XEXP (src, 0)))))
  27867. +     {
  27868. +       updates_by_const = 1;
  27869. +       offst_update = GET_MODE_SIZE (GET_MODE (dest));
  27870. +       if (GET_CODE (XEXP (dest, 0)) == PRE_DEC ||
  27871. +           GET_CODE (XEXP (dest, 0)) == POST_DEC)
  27872. +         {
  27873. +           offst_update *= -1;
  27874. +         }
  27875. +       regno_updated = STACK_POINTER_REGNUM;
  27876. +       reg_to_update = stack_pointer_rtx;
  27877. +     }
  27878. +   if (!updates_by_const)
  27879. +     {
  27880. +       return (0);
  27881. +     }
  27882. +   if (!reg_overlap_mentioned_p (reg_to_update, PATTERN (next)))
  27883. +     {
  27884. +       return (0);
  27885. +     }
  27886. +   if (GET_CODE (dest) == MEM)
  27887. +     {
  27888. +       if (GET_CODE (next_src) == MEM
  27889. +            && true_dependence (dest, next_src))
  27890. +         {
  27891. +           return (0);
  27892. +         }
  27893. +       else if (GET_CODE (next_src) != REG)
  27894. +         {
  27895. +           fmt = GET_RTX_FORMAT (GET_CODE (next_src));
  27896. +           length = GET_RTX_LENGTH (GET_CODE (next_src));
  27897. +           for (i=0; i<length; i++)
  27898. +             {
  27899. +               if (fmt[i] == 'e' && GET_CODE (XEXP (next_src, i)) == MEM)
  27900. +                 {
  27901. +                   if (true_dependence (dest, XEXP (next_src, i)))
  27902. +                     {
  27903. +                       return (0);
  27904. +                     }
  27905. +                 }
  27906. +             }
  27907. +         }
  27908. +       if (GET_CODE (next_dest) == MEM
  27909. +            && true_dependence (dest, next_dest))
  27910. +         {
  27911. +           return (0);
  27912. +         }
  27913. +     }
  27914. +   if (GET_CODE (src) == MEM)
  27915. +     {
  27916. +       if (GET_CODE (next_dest) == MEM
  27917. +            && true_dependence (src, next_dest))
  27918. +         {
  27919. +           return (0);
  27920. +         }
  27921. +     }
  27922. +   /* First check that regno_updated is not used in next with any
  27923. +      other mode */
  27924. +   init_undo_buf ();
  27925. +   subst_in_insn (next, PATTERN (next), reg_to_update, const0_rtx, 0, 0);
  27926. +   if (reg_overlap_mentioned_p (reg_to_update, PATTERN (next)))
  27927. +     {
  27928. +       loop_undo_all ();
  27929. +       return (0);
  27930. +     }
  27931. +   loop_undo_all ();
  27932. +   /* Now substitute reg_to_update with  reg_to_update + offst_update.  */
  27933. +   storage = (char *) oballoc (0);
  27934. +   /* Since may be sharing of rtl */
  27935. +   copy_dest = copy_rtx (next_dest);
  27936. +   copy_src = copy_rtx (next_src);
  27937. +   SET_SRC (PATTERN (next)) = copy_src;
  27938. +   SET_DEST (PATTERN (next)) = copy_dest;
  27939. +   init_undo_buf ();
  27940. +   subst_in_insn (next, PATTERN (next), reg_to_update,
  27941. +                  gen_rtx (PLUS , GET_MODE (reg_to_update), reg_to_update,
  27942. +                           gen_rtx (CONST_INT, 0, offst_update)), 0, 0);
  27943. + #ifdef REWRITE_ADDRESS
  27944. +   if (GET_CODE (copy_dest) == MEM)
  27945. +     {
  27946. +       REWRITE_ADDRESS (copy_dest);
  27947. +     }
  27948. +   if (GET_CODE (copy_src) == MEM)
  27949. +     {
  27950. +       REWRITE_ADDRESS (copy_src);
  27951. +     }
  27952. +   else
  27953. +     {
  27954. +       fmt = GET_RTX_FORMAT (GET_CODE (copy_src));
  27955. +       length = GET_RTX_LENGTH (GET_CODE (copy_src));
  27956. +       for (i=0; i<length; i++)
  27957. +         {
  27958. +           if (fmt[i] == 'e' && GET_CODE (XEXP (copy_src, i)) == MEM)
  27959. +             {
  27960. +               REWRITE_ADDRESS (XEXP (copy_src, i));
  27961. +             }
  27962. +         }
  27963. +     }
  27964. + #endif
  27965. +   if ((insn_code_number = recog (PATTERN (next), next, 0)) < 0)
  27966. +     {
  27967. +       loop_undo_all ();
  27968. +       SET_DEST (PATTERN (next)) = next_dest;
  27969. +       SET_SRC (PATTERN (next)) = next_src;
  27970. +       obfree (storage);
  27971. +       return (0);
  27972. +     }
  27973. +   else
  27974. +     {
  27975. + #ifdef REGISTER_CONSTRAINTS
  27976. +       save_code = INSN_CODE (next);
  27977. +       INSN_CODE (next) = insn_code_number;
  27978. +       insn_extract (next);
  27979. +       if (!constrain_operands (insn_code_number, 1))
  27980. +     {
  27981. +       loop_undo_all ();
  27982. +           SET_DEST (PATTERN (next)) = next_dest;
  27983. +           SET_SRC (PATTERN (next)) = next_src;
  27984. +       INSN_CODE (next) = save_code;
  27985. +           obfree (storage);
  27986. +       return (0);
  27987. +     }
  27988. + #endif
  27989. +     }
  27990. +   return (1);
  27991. + }
  27992. + #endif
  27993.   #endif /* INSN_SCHEDULING */
  27994. diff -rNci gcc-2.7.2/stmt.c gcc-2.7.2p/stmt.c
  27995. *** gcc-2.7.2/stmt.c    Tue Sep 12 23:01:54 1995
  27996. --- gcc-2.7.2p/stmt.c    Thu Jun 15 12:08:17 1995
  27997. ***************
  27998. *** 467,472 ****
  27999. --- 467,482 ----
  28000.   static void emit_jump_if_reachable    PROTO((rtx));
  28001.   static void emit_case_nodes        PROTO((rtx, case_node_ptr, rtx, tree));
  28002.   
  28003. + int bc_expand_exit_loop_if_false ();
  28004. + void bc_expand_start_cond ();
  28005. + void bc_expand_end_cond ();
  28006. + void bc_expand_start_else ();
  28007. + void bc_expand_end_bindings ();
  28008. + void bc_expand_start_case ();
  28009. + void bc_check_for_full_enumeration_handling ();
  28010. + void bc_expand_end_case ();
  28011. + void bc_expand_decl ();
  28012.   extern rtx bc_allocate_local ();
  28013.   extern rtx bc_allocate_variable_array ();
  28014.   
  28015. ***************
  28016. *** 553,560 ****
  28017.         last_insn = get_last_insn ();
  28018.         if (!optimize
  28019.         && (GET_CODE (last_insn) == CODE_LABEL
  28020. !           || (GET_CODE (last_insn) == NOTE
  28021. !           && prev_real_insn (last_insn) == 0)))
  28022.       emit_insn (gen_nop ());
  28023.       }
  28024.   }
  28025. --- 563,569 ----
  28026.         last_insn = get_last_insn ();
  28027.         if (!optimize
  28028.         && (GET_CODE (last_insn) == CODE_LABEL
  28029. !           || prev_real_insn (last_insn) == 0))
  28030.       emit_insn (gen_nop ());
  28031.       }
  28032.   }
  28033. ***************
  28034. *** 1246,1252 ****
  28035.             f->before_jump
  28036.           = emit_insns_after (cleanup_insns, f->before_jump);
  28037.   
  28038. !           f->cleanup_list_list = TREE_CHAIN (lists);
  28039.           }
  28040.   
  28041.       if (stack_level)
  28042. --- 1255,1261 ----
  28043.             f->before_jump
  28044.           = emit_insns_after (cleanup_insns, f->before_jump);
  28045.   
  28046. !           TREE_VALUE (lists) = 0;
  28047.           }
  28048.   
  28049.       if (stack_level)
  28050. ***************
  28051. *** 1508,1514 ****
  28052.     for (tail = inputs; tail; tail = TREE_CHAIN (tail))
  28053.       {
  28054.         int j;
  28055. -       int allows_reg = 0;
  28056.   
  28057.         /* If there's an erroneous arg, emit no insn,
  28058.        because the ASM_INPUT would get VOIDmode
  28059. --- 1517,1522 ----
  28060. ***************
  28061. *** 1524,1588 ****
  28062.   
  28063.         /* Make sure constraint has neither `=' nor `+'.  */
  28064.   
  28065. !       for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)) - 1; j++)
  28066. !     switch (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j])
  28067.         {
  28068. -       case '+':   case '=':
  28069.           error ("input operand constraint contains `%c'",
  28070.              TREE_STRING_POINTER (TREE_PURPOSE (tail))[j]);
  28071.           return;
  28072. -       case '?':  case '!':  case '*':  case '%':  case '&':
  28073. -       case 'V':  case 'm':  case 'o':  case '<':  case '>':
  28074. -       case 'E':  case 'F':  case 'G':  case 'H':  case 'X':
  28075. -       case 's':  case 'i':  case 'n':
  28076. -       case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
  28077. -       case 'N':  case 'O':  case 'P':  case ',':
  28078. - #ifdef EXTRA_CONSTRAINT
  28079. -       case 'Q':  case 'R':  case 'S':  case 'T':  case 'U':
  28080. - #endif
  28081. -         break;
  28082. -       case '0':  case '1':  case '2':  case '3':  case '4':
  28083. -       case 'p':  case 'g':  case 'r':
  28084. -       default:
  28085. -         allows_reg = 1;
  28086. -         break;
  28087.         }
  28088.   
  28089. -       if (! allows_reg)
  28090. -     mark_addressable (TREE_VALUE (tail));
  28091.         XVECEXP (body, 3, i)      /* argvec */
  28092.       = expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0);
  28093.         if (CONSTANT_P (XVECEXP (body, 3, i))
  28094.         && ! general_operand (XVECEXP (body, 3, i),
  28095.                   TYPE_MODE (TREE_TYPE (TREE_VALUE (tail)))))
  28096. !     {
  28097. !       if (allows_reg)
  28098. !         XVECEXP (body, 3, i)
  28099. !           = force_reg (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
  28100. !                XVECEXP (body, 3, i));
  28101. !       else
  28102. !         XVECEXP (body, 3, i)
  28103. !           = force_const_mem (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
  28104. !                  XVECEXP (body, 3, i));
  28105. !     }
  28106. !       if (! allows_reg
  28107. !       && (GET_CODE (XVECEXP (body, 3, i)) == REG
  28108. !           || GET_CODE (XVECEXP (body, 3, i)) == SUBREG
  28109. !           || GET_CODE (XVECEXP (body, 3, i)) == CONCAT))
  28110. !     {
  28111. !       tree type = TREE_TYPE (TREE_VALUE (tail));
  28112. !       rtx memloc = assign_stack_temp (TYPE_MODE (type),
  28113. !                       int_size_in_bytes (type), 1);
  28114. !       MEM_IN_STRUCT_P (memloc) = AGGREGATE_TYPE_P (type);
  28115. !       emit_move_insn (memloc, XVECEXP (body, 3, i));
  28116. !       XVECEXP (body, 3, i) = memloc;
  28117. !     }
  28118. !       
  28119.         XVECEXP (body, 4, i)      /* constraints */
  28120.       = gen_rtx (ASM_INPUT, TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
  28121.              TREE_STRING_POINTER (TREE_PURPOSE (tail)));
  28122. --- 1532,1554 ----
  28123.   
  28124.         /* Make sure constraint has neither `=' nor `+'.  */
  28125.   
  28126. !       for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)); j++)
  28127. !     if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '='
  28128. !         || TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '+')
  28129.         {
  28130.           error ("input operand constraint contains `%c'",
  28131.              TREE_STRING_POINTER (TREE_PURPOSE (tail))[j]);
  28132.           return;
  28133.         }
  28134.   
  28135.         XVECEXP (body, 3, i)      /* argvec */
  28136.       = expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0);
  28137.         if (CONSTANT_P (XVECEXP (body, 3, i))
  28138.         && ! general_operand (XVECEXP (body, 3, i),
  28139.                   TYPE_MODE (TREE_TYPE (TREE_VALUE (tail)))))
  28140. !     XVECEXP (body, 3, i)
  28141. !       = force_reg (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
  28142. !                XVECEXP (body, 3, i));
  28143.         XVECEXP (body, 4, i)      /* constraints */
  28144.       = gen_rtx (ASM_INPUT, TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
  28145.              TREE_STRING_POINTER (TREE_PURPOSE (tail)));
  28146. ***************
  28147. *** 1885,1891 ****
  28148.     momentary = suspend_momentary ();
  28149.     t = make_node (RTL_EXPR);
  28150.     resume_momentary (momentary);
  28151. -   do_pending_stack_adjust ();
  28152.     start_sequence_for_rtl_expr (t);
  28153.     NO_DEFER_POP;
  28154.     expr_stmts_for_value++;
  28155. --- 1851,1856 ----
  28156. ***************
  28157. *** 2757,2816 ****
  28158.         && TYPE_MODE (TREE_TYPE (retval_rhs)) == BLKmode
  28159.         && GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) == REG)
  28160.       {
  28161. !       int i, bitpos, xbitpos;
  28162.         int big_endian_correction = 0;
  28163.         int bytes = int_size_in_bytes (TREE_TYPE (retval_rhs));
  28164.         int n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
  28165. -       int bitsize = MIN (TYPE_ALIGN (TREE_TYPE (retval_rhs)),BITS_PER_WORD);
  28166.         rtx *result_pseudos = (rtx *) alloca (sizeof (rtx) * n_regs);
  28167. !       rtx result_reg, src, dst;
  28168.         rtx result_val = expand_expr (retval_rhs, NULL_RTX, VOIDmode, 0);
  28169.         enum machine_mode tmpmode, result_reg_mode;
  28170.   
  28171. !       /* Structures whose size is not a multiple of a word are aligned
  28172. !      to the least significant byte (to the right).  On a BYTES_BIG_ENDIAN
  28173. !      machine, this means we must skip the empty high order bytes when
  28174. !      calculating the bit offset.  */
  28175. !       if (BYTES_BIG_ENDIAN && bytes % UNITS_PER_WORD)
  28176. !     big_endian_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
  28177. !                           * BITS_PER_UNIT));
  28178. !       /* Copy the structure BITSIZE bits at a time.  */ 
  28179. !       for (bitpos = 0, xbitpos = big_endian_correction;
  28180. !        bitpos < bytes * BITS_PER_UNIT;
  28181. !        bitpos += bitsize, xbitpos += bitsize)
  28182. !     {
  28183. !       /* We need a new destination pseudo each time xbitpos is
  28184. !          on a word boundary and when xbitpos == big_endian_correction
  28185. !          (the first time through).  */
  28186. !       if (xbitpos % BITS_PER_WORD == 0
  28187. !           || xbitpos == big_endian_correction)
  28188.           {
  28189. !           /* Generate an appropriate register.  */
  28190. !           dst = gen_reg_rtx (word_mode);
  28191. !           result_pseudos[xbitpos / BITS_PER_WORD] = dst;
  28192.   
  28193. !           /* Clobber the destination before we move anything into it.  */
  28194. !           emit_insn (gen_rtx (CLOBBER, VOIDmode, dst));
  28195.           }
  28196. -       /* We need a new source operand each time bitpos is on a word
  28197. -          boundary.  */
  28198. -       if (bitpos % BITS_PER_WORD == 0)
  28199. -         src = operand_subword_force (result_val,
  28200. -                      bitpos / BITS_PER_WORD,
  28201. -                      BLKmode);
  28202. -       /* Use bitpos for the source extraction (left justified) and
  28203. -          xbitpos for the destination store (right justified).  */
  28204. -       store_bit_field (dst, bitsize, xbitpos % BITS_PER_WORD, word_mode,
  28205. -                extract_bit_field (src, bitsize,
  28206. -                           bitpos % BITS_PER_WORD, 1,
  28207. -                           NULL_RTX, word_mode,
  28208. -                           word_mode,
  28209. -                           bitsize / BITS_PER_UNIT,
  28210. -                           BITS_PER_WORD),
  28211. -                bitsize / BITS_PER_UNIT, BITS_PER_WORD);
  28212.       }
  28213.   
  28214.         /* Find the smallest integer mode large enough to hold the
  28215. --- 2722,2772 ----
  28216.         && TYPE_MODE (TREE_TYPE (retval_rhs)) == BLKmode
  28217.         && GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) == REG)
  28218.       {
  28219. !       int i;
  28220.         int big_endian_correction = 0;
  28221.         int bytes = int_size_in_bytes (TREE_TYPE (retval_rhs));
  28222.         int n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
  28223.         rtx *result_pseudos = (rtx *) alloca (sizeof (rtx) * n_regs);
  28224. !       rtx result_reg;
  28225.         rtx result_val = expand_expr (retval_rhs, NULL_RTX, VOIDmode, 0);
  28226.         enum machine_mode tmpmode, result_reg_mode;
  28227.   
  28228. !       /* Structures smaller than a word are aligned to the least significant
  28229. !      byte (to the right).  On a BYTES_BIG_ENDIAN machine, this means we
  28230. !      must skip the empty high order bytes when calculating the bit
  28231. !      offset.  */
  28232. !       if (BYTES_BIG_ENDIAN && bytes < UNITS_PER_WORD)
  28233. !     big_endian_correction = (BITS_PER_WORD - (bytes * BITS_PER_UNIT));
  28234. !       for (i = 0; i < n_regs; i++)
  28235. !     {
  28236. !       rtx reg = gen_reg_rtx (word_mode);
  28237. !       rtx word = operand_subword_force (result_val, i, BLKmode);
  28238. !       int bitsize = MIN (TYPE_ALIGN (TREE_TYPE (retval_rhs)),BITS_PER_WORD);
  28239. !       int bitpos;
  28240. !       result_pseudos[i] = reg;
  28241. !       /* Clobber REG and move each partword into it.  Ensure we don't
  28242. !          go past the end of the structure.  Note that the loop below
  28243. !          works because we've already verified that padding and
  28244. !          endianness are compatible.  */
  28245. !       emit_insn (gen_rtx (CLOBBER, VOIDmode, reg));
  28246. !       for (bitpos = 0;
  28247. !            bitpos < BITS_PER_WORD && bytes > 0;
  28248. !            bitpos += bitsize, bytes -= bitsize / BITS_PER_UNIT)
  28249.           {
  28250. !           int xbitpos = bitpos + big_endian_correction;
  28251.   
  28252. !           store_bit_field (reg, bitsize, xbitpos, word_mode,
  28253. !                    extract_bit_field (word, bitsize, bitpos, 1,
  28254. !                           NULL_RTX, word_mode,
  28255. !                           word_mode,
  28256. !                           bitsize / BITS_PER_UNIT,
  28257. !                           BITS_PER_WORD),
  28258. !                    bitsize / BITS_PER_UNIT, BITS_PER_WORD);
  28259.           }
  28260.       }
  28261.   
  28262.         /* Find the smallest integer mode large enough to hold the
  28263. ***************
  28264. *** 3310,3316 ****
  28265.   }
  28266.   
  28267.   /* Generate RTL for the automatic variable declaration DECL.
  28268. !    (Other kinds of declarations are simply ignored if seen here.)  */
  28269.   
  28270.   void
  28271.   expand_decl (decl)
  28272. --- 3266,3287 ----
  28273.   }
  28274.   
  28275.   /* Generate RTL for the automatic variable declaration DECL.
  28276. !    (Other kinds of declarations are simply ignored if seen here.)
  28277. !    CLEANUP is an expression to be executed at exit from this binding contour;
  28278. !    for example, in C++, it might call the destructor for this variable.
  28279. !    If CLEANUP contains any SAVE_EXPRs, then you must preevaluate them
  28280. !    either before or after calling `expand_decl' but before compiling
  28281. !    any subsequent expressions.  This is because CLEANUP may be expanded
  28282. !    more than once, on different branches of execution.
  28283. !    For the same reason, CLEANUP may not contain a CALL_EXPR
  28284. !    except as its topmost node--else `preexpand_calls' would get confused.
  28285. !    If CLEANUP is nonzero and DECL is zero, we record a cleanup
  28286. !    that is not associated with any particular variable.
  28287. !    There is no special support here for C++ constructors.
  28288. !    They should be handled by the proper code in DECL_INITIAL.  */
  28289.   
  28290.   void
  28291.   expand_decl (decl)
  28292. ***************
  28293. *** 3683,3689 ****
  28294.      for example, in C++, it might call the destructor for this variable.
  28295.   
  28296.      If CLEANUP contains any SAVE_EXPRs, then you must preevaluate them
  28297. !    either before or after calling `expand_decl_cleanup' but before compiling
  28298.      any subsequent expressions.  This is because CLEANUP may be expanded
  28299.      more than once, on different branches of execution.
  28300.      For the same reason, CLEANUP may not contain a CALL_EXPR
  28301. --- 3654,3660 ----
  28302.      for example, in C++, it might call the destructor for this variable.
  28303.   
  28304.      If CLEANUP contains any SAVE_EXPRs, then you must preevaluate them
  28305. !    either before or after calling `expand_decl' but before compiling
  28306.      any subsequent expressions.  This is because CLEANUP may be expanded
  28307.      more than once, on different branches of execution.
  28308.      For the same reason, CLEANUP may not contain a CALL_EXPR
  28309. ***************
  28310. *** 3726,3733 ****
  28311.     struct nesting *thisblock = block_stack;
  28312.     rtx x;
  28313.   
  28314. !   expand_decl (decl);
  28315. !   expand_decl_cleanup (decl, cleanup);
  28316.     x = DECL_RTL (decl);
  28317.   
  28318.     while (decl_elts)
  28319. --- 3697,3703 ----
  28320.     struct nesting *thisblock = block_stack;
  28321.     rtx x;
  28322.   
  28323. !   expand_decl (decl, cleanup);
  28324.     x = DECL_RTL (decl);
  28325.   
  28326.     while (decl_elts)
  28327. diff -rNci gcc-2.7.2/stor-layout.c gcc-2.7.2p/stor-layout.c
  28328. *** gcc-2.7.2/stor-layout.c    Tue Oct  3 23:15:07 1995
  28329. --- gcc-2.7.2p/stor-layout.c    Thu Jun 15 12:08:47 1995
  28330. ***************
  28331. *** 81,96 ****
  28332.     return chain;
  28333.   }
  28334.   
  28335. - void
  28336. - put_pending_sizes (chain)
  28337. -      tree chain;
  28338. - {
  28339. -   if (pending_sizes)
  28340. -     abort ();
  28341. -   pending_sizes = chain;
  28342. - }
  28343.   /* Given a size SIZE that may not be a constant, return a SAVE_EXPR
  28344.      to serve as the actual size-expression for a type or decl.  */
  28345.   
  28346. --- 81,86 ----
  28347. ***************
  28348. *** 747,774 ****
  28349.       if (index && TYPE_MAX_VALUE (index) && TYPE_MIN_VALUE (index)
  28350.           && TYPE_SIZE (element))
  28351.         {
  28352. !         tree ub = TYPE_MAX_VALUE (index);
  28353. !         tree lb = TYPE_MIN_VALUE (index);
  28354. !         tree length;
  28355. !         /* If UB is max (lb - 1, x), remove the MAX_EXPR since the
  28356. !            test for negative below covers it.  */
  28357. !         if (TREE_CODE (ub) == MAX_EXPR
  28358. !         && TREE_CODE (TREE_OPERAND (ub, 0)) == MINUS_EXPR
  28359. !         && integer_onep (TREE_OPERAND (TREE_OPERAND (ub, 0), 1))
  28360. !         && operand_equal_p (TREE_OPERAND (TREE_OPERAND (ub, 0), 0),
  28361. !                     lb, 0))
  28362. !           ub = TREE_OPERAND (ub, 1);
  28363. !         else if (TREE_CODE (ub) == MAX_EXPR
  28364. !              && TREE_CODE (TREE_OPERAND (ub, 1)) == MINUS_EXPR
  28365. !              && integer_onep (TREE_OPERAND (TREE_OPERAND (ub, 1), 1))
  28366. !              && operand_equal_p (TREE_OPERAND (TREE_OPERAND (ub, 1),
  28367. !                                0),
  28368. !                      lb, 0))
  28369. !           ub = TREE_OPERAND (ub, 0);
  28370. !         length = size_binop (PLUS_EXPR, size_one_node,
  28371. !                  size_binop (MINUS_EXPR, ub, lb));
  28372.   
  28373.           /* If neither bound is a constant and sizetype is signed, make
  28374.              sure the size is never negative.  We should really do this
  28375. --- 737,746 ----
  28376.       if (index && TYPE_MAX_VALUE (index) && TYPE_MIN_VALUE (index)
  28377.           && TYPE_SIZE (element))
  28378.         {
  28379. !         tree length
  28380. !           = size_binop (PLUS_EXPR, size_one_node,
  28381. !                 size_binop (MINUS_EXPR, TYPE_MAX_VALUE (index),
  28382. !                     TYPE_MIN_VALUE (index)));
  28383.   
  28384.           /* If neither bound is a constant and sizetype is signed, make
  28385.              sure the size is never negative.  We should really do this
  28386. diff -rNci gcc-2.7.2/stupid.c gcc-2.7.2p/stupid.c
  28387. *** gcc-2.7.2/stupid.c    Sun Oct 29 12:45:22 1995
  28388. --- gcc-2.7.2p/stupid.c    Thu Jun 15 12:09:19 1995
  28389. ***************
  28390. *** 423,441 ****
  28391.   
  28392.     if (code == SET || code == CLOBBER)
  28393.       {
  28394. !       if (SET_DEST (x) != 0
  28395. !       && (GET_CODE (SET_DEST (x)) == REG
  28396. !           || (GET_CODE (SET_DEST (x)) == SUBREG
  28397. !           && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
  28398. !           && (REGNO (SUBREG_REG (SET_DEST (x)))
  28399. !               >= FIRST_PSEUDO_REGISTER))))
  28400.       {
  28401.         /* Register is being assigned.  */
  28402. !       /* If setting a SUBREG, we treat the entire reg as being set.  */
  28403. !       if (GET_CODE (SET_DEST (x)) == SUBREG)
  28404. !         regno = REGNO (SUBREG_REG (SET_DEST (x)));
  28405. !       else
  28406. !         regno = REGNO (SET_DEST (x));
  28407.   
  28408.         /* For hard regs, update the where-live info.  */
  28409.         if (regno < FIRST_PSEUDO_REGISTER)
  28410. --- 423,432 ----
  28411.   
  28412.     if (code == SET || code == CLOBBER)
  28413.       {
  28414. !       if (SET_DEST (x) != 0 && GET_CODE (SET_DEST (x)) == REG)
  28415.       {
  28416.         /* Register is being assigned.  */
  28417. !       regno = REGNO (SET_DEST (x));
  28418.   
  28419.         /* For hard regs, update the where-live info.  */
  28420.         if (regno < FIRST_PSEUDO_REGISTER)
  28421. diff -rNci gcc-2.7.2/toplev.c gcc-2.7.2p/toplev.c
  28422. *** gcc-2.7.2/toplev.c    Fri Oct 20 21:56:35 1995
  28423. --- gcc-2.7.2p/toplev.c    Tue Jan 23 09:25:32 1996
  28424. ***************
  28425. *** 205,211 ****
  28426. --- 201,209 ----
  28427.   int combine_dump = 0;
  28428.   int sched_dump = 0;
  28429.   int local_reg_dump = 0;
  28430. + int memory_simplify_dump = 0; /* intel2 */
  28431.   int global_reg_dump = 0;
  28432. + int loop2_dump = 0; /* intel1 */
  28433.   int sched2_dump = 0;
  28434.   int jump2_opt_dump = 0;
  28435.   int dbr_sched_dump = 0;
  28436. ***************
  28437. *** 374,379 ****
  28438. --- 372,413 ----
  28439.   /* Nonzero enables strength-reduction in loop.c.  */
  28440.   
  28441.   int flag_strength_reduce = 0;
  28442. + /* intel1 my optimization controllers */
  28443. + int flag_opt_reg_use = 0;
  28444. + int flag_all_mem_givs = 0;
  28445. + int flag_reduce_index_givs = 0;
  28446. + int flag_peep_spills = 0;
  28447. + int flag_loop_after_global = 0;
  28448. + int flag_jump_back = 0;
  28449. + int flag_copy_prop = 0;
  28450. + int flag_lift_stores = 0;
  28451. + int flag_runtime_lift_stores = 0;
  28452. + int flag_compare_elim = 0;
  28453. + int flag_sign_extension_elim = 0;
  28454. + int flag_sftwr_pipe = 0;
  28455. + int flag_opt_jumps_out = 0;
  28456. + int flag_replace_mem = 0;
  28457. + int flag_replace_stack_mem = 0;
  28458. + int flag_reg_reg_copy_opt = 0;
  28459. + int flag_do_offload = 0;
  28460. + int flag_opt_reg_stack = 0;
  28461. + int flag_correct_cse_mistakes = 0;
  28462. + int flag_push_load_into_loop = 0;
  28463. + int flag_risc = 0;
  28464. + int flag_risc_const = 0;
  28465. + int flag_risc_mem_dest = 0;    /* intel2 */
  28466. + int flag_replace_reload_regs = 0;
  28467. + int flag_recombine = 0;
  28468. + int flag_swap_for_agi = 0;
  28469. + int flag_no_omit_frame_pointer = 0;
  28470. + int flag_no_risc = 0;
  28471. + int flag_no_risc_const = 0;
  28472. + int flag_no_risc_mem_dest = 0;    /* intel2 */
  28473. + int flag_no_recombine = 0;
  28474. + int flag_schedule_stack_reg_insns = 0;
  28475. + int flag_interleave_stack_non_stack = 0;
  28476. + int flag_no_schedule_stack_reg_insns = 0;
  28477. + int flag_no_interleave_stack_non_stack = 0;
  28478.   
  28479.   /* Nonzero enables loop unrolling in unroll.c.  Only loops for which the
  28480.      number of iterations can be calculated at compile-time (UNROLL_COMPLETELY,
  28481. ***************
  28482. *** 567,573 ****
  28483.     {"verbose-asm", &flag_verbose_asm, 1},
  28484.     {"gnu-linker", &flag_gnu_linker, 1},
  28485.     {"pack-struct", &flag_pack_struct, 1},
  28486. !   {"bytecode", &output_bytecode, 1}
  28487.   };
  28488.   
  28489.   /* Table of language-specific options.  */
  28490. --- 601,642 ----
  28491.     {"verbose-asm", &flag_verbose_asm, 1},
  28492.     {"gnu-linker", &flag_gnu_linker, 1},
  28493.     {"pack-struct", &flag_pack_struct, 1},
  28494. !   {"bytecode", &output_bytecode, 1},
  28495. !   /* intel1 */
  28496. !   {"compare-elim", &flag_compare_elim, 1},
  28497. !   {"sign-extension-elim", &flag_sign_extension_elim, 1},
  28498. !   {"jump-back", &flag_jump_back, 1},
  28499. !   {"loop-after-global", &flag_loop_after_global, 1},
  28500. !   {"opt-reg-use", &flag_opt_reg_use, 1},
  28501. !   {"all-mem-givs", &flag_all_mem_givs, 1},
  28502. !   {"reduce-index-givs", &flag_reduce_index_givs, 1},
  28503. !   {"peep-spills", &flag_peep_spills, 1},
  28504. !   {"copy-prop", &flag_copy_prop, 1},
  28505. !   {"lift-stores", &flag_lift_stores, 1},
  28506. !   {"runtime-lift-stores", &flag_runtime_lift_stores, 1},
  28507. !   {"do-offload", &flag_do_offload, 1},
  28508. !   {"opt-reg-stack", &flag_opt_reg_stack, 1},
  28509. !   {"correct-cse-mistakes", &flag_correct_cse_mistakes, 1},
  28510. !   {"spl", &flag_sftwr_pipe, 1},
  28511. !   {"opt-jumps-out", &flag_opt_jumps_out, 1},
  28512. !   {"replace-mem", &flag_replace_mem, 1},
  28513. !   {"replace-stack-mem", &flag_replace_stack_mem, 1},
  28514. !   {"no-interleave-stack-non-stack", &flag_no_interleave_stack_non_stack, 1},
  28515. !   {"interleave-stack-non-stack", &flag_interleave_stack_non_stack, 1},
  28516. !   {"no-schedule-stack-reg-insns", &flag_no_schedule_stack_reg_insns, 1},
  28517. !   {"schedule-stack-reg-insns", &flag_schedule_stack_reg_insns, 1},
  28518. !   {"reg-reg-copy-opt", &flag_reg_reg_copy_opt, 1},
  28519. !   {"push-load-into-loop", &flag_push_load_into_loop, 1},
  28520. !   {"swap-for-agi", &flag_swap_for_agi, 1},
  28521. !   {"no-recombine", &flag_no_recombine, 1},
  28522. !   {"recombine", &flag_recombine, 1},
  28523. !   {"no-risc", &flag_no_risc, 1},
  28524. !   {"risc", &flag_risc, 1},
  28525. !   {"no-risc-const", &flag_no_risc_const, 1},
  28526. !   {"risc-const", &flag_risc_const, 1},
  28527. !   {"replace-reload-regs", &flag_replace_reload_regs, 1},
  28528. !   {"no-risc-mem-dest", &flag_no_risc_mem_dest, 1},    /* intel2 */
  28529. !   {"risc-mem-dest", &flag_risc_mem_dest, 1},    /* intel2 */
  28530.   };
  28531.   
  28532.   /* Table of language-specific options.  */
  28533. ***************
  28534. *** 756,761 ****
  28535. --- 825,833 ----
  28536.   FILE *sched_dump_file;
  28537.   FILE *local_reg_dump_file;
  28538.   FILE *global_reg_dump_file;
  28539. + FILE *memory_simplify_dump_file; /* intel2 */
  28540. + /* intel1 */
  28541. + FILE *loop2_dump_file;
  28542.   FILE *sched2_dump_file;
  28543.   FILE *jump2_opt_dump_file;
  28544.   FILE *dbr_sched_dump_file;
  28545. ***************
  28546. *** 775,780 ****
  28547. --- 847,855 ----
  28548.   int sched_time;
  28549.   int local_alloc_time;
  28550.   int global_alloc_time;
  28551. + int memory_simplify_time; /* intel2 */
  28552. + /* intel1 */
  28553. + int loop2_time;
  28554.   int sched2_time;
  28555.   int dbr_sched_time;
  28556.   int shorten_branch_time;
  28557. ***************
  28558. *** 926,931 ****
  28559. --- 1001,1010 ----
  28560.       fflush (local_reg_dump_file);
  28561.     if (global_reg_dump_file)
  28562.       fflush (global_reg_dump_file);
  28563. +   if (memory_simplify_dump_file) /* intel2 */
  28564. +       fflush (memory_simplify_dump_file);
  28565. +   if (loop2_dump_file) /* intel1 */
  28566. +     fflush (loop2_dump_file);
  28567.     if (sched2_dump_file)
  28568.       fflush (sched2_dump_file);
  28569.     if (jump2_opt_dump_file)
  28570. ***************
  28571. *** 1052,1059 ****
  28572.     (*print_error_function) (file);
  28573.   
  28574.     if (input_file_stack && input_file_stack->next != 0
  28575. !       && input_file_stack_tick != last_error_tick
  28576. !       && file == input_filename)
  28577.       {
  28578.         fprintf (stderr, "In file included");
  28579.         for (p = input_file_stack->next; p; p = p->next)
  28580. --- 1131,1137 ----
  28581.     (*print_error_function) (file);
  28582.   
  28583.     if (input_file_stack && input_file_stack->next != 0
  28584. !       && input_file_stack_tick != last_error_tick)
  28585.       {
  28586.         fprintf (stderr, "In file included");
  28587.         for (p = input_file_stack->next; p; p = p->next)
  28588. ***************
  28589. *** 1085,1092 ****
  28590.       HOST_WIDE_INT v1 = va_arg(ap, HOST_WIDE_INT);
  28591.       HOST_WIDE_INT v2 = va_arg(ap, HOST_WIDE_INT);
  28592.       HOST_WIDE_INT v3 = va_arg(ap, HOST_WIDE_INT);
  28593. !     HOST_WIDE_INT v4 = va_arg(ap, HOST_WIDE_INT);
  28594. !     fprintf (stderr, s, v1, v2, v3, v4);
  28595.     }
  28596.   #endif
  28597.   }
  28598. --- 1163,1169 ----
  28599.       HOST_WIDE_INT v1 = va_arg(ap, HOST_WIDE_INT);
  28600.       HOST_WIDE_INT v2 = va_arg(ap, HOST_WIDE_INT);
  28601.       HOST_WIDE_INT v3 = va_arg(ap, HOST_WIDE_INT);
  28602. !     fprintf (stderr, s, v1, v2, v3);
  28603.     }
  28604.   #endif
  28605.   }
  28606. ***************
  28607. *** 1863,1883 ****
  28608.   }
  28609.   
  28610.   /* Strip off a legitimate source ending from the input string NAME of
  28611. !    length LEN.  Rather than having to know the names used by all of
  28612. !    our front ends, we strip off an ending of a period followed by one,
  28613. !    two, or three characters.  */
  28614.   
  28615.   void
  28616.   strip_off_ending (name, len)
  28617.        char *name;
  28618.        int len;
  28619.   {
  28620. !   if (len > 2 && name[len - 2] == '.')
  28621. !     name[len - 2] = '\0';
  28622. !   else if (len > 3 && name[len - 3] == '.')
  28623. !     name[len - 3] = '\0';
  28624. !   else if (len > 4 && name[len - 4] == '.')
  28625. !     name[len - 4] = '\0';
  28626.   }
  28627.   
  28628.   /* Output a quoted string.  */
  28629. --- 1940,1978 ----
  28630.   }
  28631.   
  28632.   /* Strip off a legitimate source ending from the input string NAME of
  28633. !    length LEN. */
  28634.   
  28635.   void
  28636.   strip_off_ending (name, len)
  28637.        char *name;
  28638.        int len;
  28639.   {
  28640. !   if (len > 2 && ! strcmp (".c", name + len - 2))
  28641. !     name[len - 2] = 0;
  28642. !   else if (len > 2 && ! strcmp (".m", name + len - 2))
  28643. !     name[len - 2] = 0;
  28644. !   else if (len > 2 && ! strcmp (".i", name + len - 2))
  28645. !     name[len - 2] = 0;
  28646. !   else if (len > 3 && ! strcmp (".ii", name + len - 3))
  28647. !     name[len - 3] = 0;
  28648. !   else if (len > 3 && ! strcmp (".co", name + len - 3))
  28649. !     name[len - 3] = 0;
  28650. !   else if (len > 3 && ! strcmp (".cc", name + len - 3))
  28651. !     name[len - 3] = 0;
  28652. !   else if (len > 2 && ! strcmp (".C", name + len - 2))
  28653. !     name[len - 2] = 0;
  28654. !   else if (len > 4 && ! strcmp (".cxx", name + len - 4))
  28655. !     name[len - 4] = 0;
  28656. !   else if (len > 4 && ! strcmp (".cpp", name + len - 4))
  28657. !     name[len - 4] = 0;
  28658. !   else if (len > 2 && ! strcmp (".f", name + len - 2))
  28659. !     name[len - 2] = 0;
  28660. !   /* Ada will use extensions like .ada, .adb, and .ads, so just test
  28661. !      for "ad".  */
  28662. !   else if (len > 4 && ! strncmp (".ad", name + len - 4, 3))
  28663. !     name[len - 4] = 0;
  28664. !   else if (len > 4 && ! strcmp (".atr", name + len - 4))
  28665. !     name[len - 4] = 0;
  28666.   }
  28667.   
  28668.   /* Output a quoted string.  */
  28669. ***************
  28670. *** 1984,1989 ****
  28671. --- 2079,2087 ----
  28672.     sched_time = 0;
  28673.     local_alloc_time = 0;
  28674.     global_alloc_time = 0;
  28675. +   memory_simplify_time = 0; /* intel2 */
  28676. +   /* intel1 */
  28677. +   loop2_time = 0;
  28678.     sched2_time = 0;
  28679.     dbr_sched_time = 0;
  28680.     shorten_branch_time = 0;
  28681. ***************
  28682. *** 2080,2085 ****
  28683. --- 2178,2194 ----
  28684.     if (global_reg_dump)
  28685.       global_reg_dump_file = open_dump_file (dump_base_name, ".greg");
  28686.   
  28687. +   /* intel1 */
  28688. +   /* If loop invariants after greg dump desired, open the output file.  */
  28689. +   if (loop2_dump)
  28690. +       loop2_dump_file = open_dump_file(dump_base_name, ".l2" );
  28691. + /* intel2 - begin */
  28692. +   /* If memory_simplify dump desired, open the output file.  */
  28693. +   if (memory_simplify_dump)
  28694. +       memory_simplify_dump_file=open_dump_file(dump_base_name, ".msim");
  28695. + /* intel2 - end */
  28696.     /* If 2nd scheduling dump desired, open the output file.  */
  28697.     if (sched2_dump)
  28698.       sched2_dump_file = open_dump_file (dump_base_name, ".sched2");
  28699. ***************
  28700. *** 2492,2497 ****
  28701. --- 2601,2612 ----
  28702.     if (global_reg_dump)
  28703.       fclose (global_reg_dump_file);
  28704.   
  28705. +   if (memory_simplify_dump)
  28706. +     fclose (memory_simplify_dump_file); /* intel2 */
  28707. +     
  28708. +   if (loop2_dump) /* intel1 */
  28709. +     fclose (loop2_dump_file);
  28710.     if (sched2_dump)
  28711.       fclose (sched2_dump_file);
  28712.   
  28713. ***************
  28714. *** 2520,2547 ****
  28715.       {
  28716.         fprintf (stderr,"\n");
  28717.         print_time ("parse", parse_time);
  28718.         if (!output_bytecode)
  28719. !     {
  28720. !       print_time ("integration", integration_time);
  28721. !       print_time ("jump", jump_time);
  28722. !       print_time ("cse", cse_time);
  28723. !       print_time ("loop", loop_time);
  28724. !       print_time ("cse2", cse2_time);
  28725. !       print_time ("flow", flow_time);
  28726. !       print_time ("combine", combine_time);
  28727. !       print_time ("sched", sched_time);
  28728. !       print_time ("local-alloc", local_alloc_time);
  28729. !       print_time ("global-alloc", global_alloc_time);
  28730. !       print_time ("sched2", sched2_time);
  28731. !       print_time ("dbranch", dbr_sched_time);
  28732. !       print_time ("shorten-branch", shorten_branch_time);
  28733. !       print_time ("stack-reg", stack_reg_time);
  28734. !       print_time ("final", final_time);
  28735. !       print_time ("varconst", varconst_time);
  28736. !       print_time ("symout", symout_time);
  28737. !       print_time ("dump", dump_time);
  28738. !     }
  28739.       }
  28740.   }
  28741.   
  28742. --- 2635,2664 ----
  28743.       {
  28744.         fprintf (stderr,"\n");
  28745.         print_time ("parse", parse_time);
  28746.         if (!output_bytecode)
  28747. !       {
  28748. !         print_time ("integration", integration_time);
  28749. !         print_time ("jump", jump_time);
  28750. !         print_time ("cse", cse_time);
  28751. !         print_time ("loop", loop_time);
  28752. !         print_time ("cse2", cse2_time);
  28753. !         print_time ("flow", flow_time);
  28754. !         print_time ("combine", combine_time);
  28755. !         print_time ("sched", sched_time);
  28756. !         print_time ("local-alloc", local_alloc_time);
  28757. !         print_time ("global-alloc", global_alloc_time);
  28758. !         print_time ("memory-simplify", memory_simplify_time); /* intel2 */
  28759. !         /* intel1 */
  28760. !         print_time ("loop2", loop2_time);
  28761. !         print_time ("sched2", sched2_time);
  28762. !         print_time ("dbranch", dbr_sched_time);
  28763. !         print_time ("shorten-branch", shorten_branch_time);
  28764. !         print_time ("stack-reg", stack_reg_time);
  28765. !         print_time ("final", final_time);
  28766. !         print_time ("varconst", varconst_time);
  28767. !         print_time ("symout", symout_time);
  28768. !         print_time ("dump", dump_time);
  28769. !       }
  28770.       }
  28771.   }
  28772.   
  28773. ***************
  28774. *** 2981,2987 ****
  28775.        and write some of the results to dump file.  */
  28776.   
  28777.         TIMEVAR (flow_time, flow_analysis (insns, max_reg_num (),
  28778. !                      flow_dump_file));
  28779.         if (warn_uninitialized)
  28780.       {
  28781.         uninitialized_vars_warning (DECL_INITIAL (decl));
  28782. --- 3098,3104 ----
  28783.        and write some of the results to dump file.  */
  28784.   
  28785.         TIMEVAR (flow_time, flow_analysis (insns, max_reg_num (),
  28786. !                      flow_dump_file /* intel2: */, 1));
  28787.         if (warn_uninitialized)
  28788.       {
  28789.         uninitialized_vars_warning (DECL_INITIAL (decl));
  28790. ***************
  28791. *** 3015,3020 ****
  28792. --- 3132,3162 ----
  28793.              fflush (combine_dump_file);
  28794.            });
  28795.   
  28796. +   /* intel1 */
  28797. + #ifdef STACK_REGS
  28798. + #ifdef IS_STACK_MODE
  28799. +   if (optimize > 0 && flag_opt_reg_stack)
  28800. +     {
  28801. +       if(stack_reg_dump)
  28802. +         {
  28803. +           TIMEVAR (dump_time,
  28804. +                {
  28805. +              fprintf (stack_reg_dump_file, "\n;; Function %s\n\n",
  28806. +                   IDENTIFIER_POINTER (DECL_NAME (decl)));
  28807. +                });
  28808. +         }
  28809. +       opt_reg_stack();
  28810. +       if(stack_reg_dump)
  28811. +         {
  28812. +           TIMEVAR (dump_time,
  28813. +                {
  28814. +              print_rtl (stack_reg_dump_file, insns);
  28815. +              fflush (stack_reg_dump_file);
  28816. +                });
  28817. +         }
  28818. +     }
  28819. + #endif
  28820. + #endif
  28821.     /* Print function header into sched dump now
  28822.        because doing the sched analysis makes some of the dump.  */
  28823.   
  28824. ***************
  28825. *** 3082,3087 ****
  28826. --- 3224,3235 ----
  28827.              failure = reload (insns, 0, global_reg_dump_file);
  28828.          });
  28829.   
  28830. +  /* intel1 */
  28831. +   if(optimize > 0 && flag_reg_reg_copy_opt)
  28832. +     {
  28833. +       reg_to_reg_copy_opt(insns, global_reg_dump_file);
  28834. +     }  
  28835.     if (global_reg_dump)
  28836.       TIMEVAR (dump_time,
  28837.            {
  28838. ***************
  28839. *** 3095,3100 ****
  28840. --- 3243,3312 ----
  28841.   
  28842.     reload_completed = 1;
  28843.   
  28844. + #ifdef STACK_REGS
  28845. +   /* intel1 */
  28846. +   if (optimize > 0 && flag_opt_reg_stack)
  28847. +     {
  28848. +       TIMEVAR (stack_reg_time, float_to_int_cmp (insns, 0));
  28849. +     }
  28850. + #endif
  28851. +   /* intel1 */
  28852. +   if (loop2_dump)
  28853. +     TIMEVAR (dump_time,
  28854. +          {
  28855. +            fprintf (loop2_dump_file, "\n;; Function %s\n\n",
  28856. +             IDENTIFIER_POINTER (DECL_NAME (decl)));
  28857. +          });
  28858. +   if(optimize>0 && flag_loop_after_global) 
  28859. +   {
  28860. +       TIMEVAR (loop2_time,
  28861. +            {
  28862. +              /* intel2 - begin */
  28863. +              if (flag_replace_reload_regs)
  28864. +                replace_reload_registers (get_insns(),
  28865. +                              loop2_dump ? loop2_dump_file : 0);
  28866. +              /* intel2 - end */
  28867. +                  loop_after_global(get_insns(),loop2_dump ? loop2_dump_file : 0); 
  28868. +            });
  28869. +   }
  28870. +   if (optimize>0 && flag_peep_spills)
  28871. +     {
  28872. +      TIMEVAR (loop2_time,
  28873. +           {
  28874. +           peep_spills(get_insns(),loop2_dump ? loop2_dump_file : 0); 
  28875. +           });
  28876. +     }
  28877. +     
  28878. +   /* Dump rtl code after loop2 opt, if we are doing that.  */
  28879. +   if (loop2_dump && flag_loop_after_global)
  28880. +     TIMEVAR (dump_time,
  28881. +          {
  28882. +            print_rtl (loop2_dump_file, insns);
  28883. +            fflush (loop2_dump_file);
  28884. +          });
  28885. + /* intel2 - begin */
  28886. +   if (optimize>0 && flag_risc)
  28887. +     {
  28888. +       if (memory_simplify_dump)
  28889. +         TIMEVAR (dump_time,
  28890. +              fprintf (memory_simplify_dump_file, "\n;; Function %s\n\n",
  28891. +                   IDENTIFIER_POINTER (DECL_NAME (decl))));
  28892. +     
  28893. +           TIMEVAR (memory_simplify_time,
  28894. +            memory_simplify (memory_simplify_dump ? memory_simplify_dump_file : 0,
  28895. +                                 insns));
  28896. +       if (memory_simplify_dump)
  28897. +         TIMEVAR (dump_time,
  28898. +              {
  28899. +                print_rtl (memory_simplify_dump_file, insns);
  28900. +                fflush (memory_simplify_dump_file);
  28901. +              });
  28902. +     }
  28903. + /* intel2 - end */
  28904.     /* On some machines, the prologue and epilogue code, or parts thereof,
  28905.        can be represented as RTL.  Doing so lets us schedule insns between
  28906.        it and the rest of the code and also allows delayed branch
  28907. ***************
  28908. *** 3126,3131 ****
  28909. --- 3338,3350 ----
  28910.            });
  28911.       }
  28912.   
  28913. +   /* intel2 - begin */
  28914. +   /* Combine those riscified insns that were not used for scheduling */
  28915. +   if (flag_risc && flag_recombine)
  28916. +     combine_unscheded (get_insns (),max_reg_num ());
  28917. +   /* intel2 - end */
  28918.   #ifdef LEAF_REGISTERS
  28919.     leaf_function = 0;
  28920.     if (optimize > 0 && only_leaf_regs_used () && leaf_function_p ())
  28921. ***************
  28922. *** 3185,3190 ****
  28923. --- 3404,3414 ----
  28924.          });
  28925.   
  28926.   #ifdef STACK_REGS
  28927. +   /* intel1 */
  28928. +   if (optimize > 0 && flag_opt_reg_stack)
  28929. +     {
  28930. +       TIMEVAR (stack_reg_time, float_to_int_cmp (insns));
  28931. +     }
  28932.     TIMEVAR (stack_reg_time, reg_to_stack (insns, stack_reg_dump_file));
  28933.     if (stack_reg_dump)
  28934.       {
  28935. ***************
  28936. *** 3196,3201 ****
  28937. --- 3420,3432 ----
  28938.            fflush (stack_reg_dump_file);
  28939.              });
  28940.       }
  28941. + /* intel1 spl */
  28942. + #ifdef STORE_NOT_SET_CC0
  28943. +   if(flag_sftwr_pipe)
  28944. +     {
  28945. +       do_spl(insns);
  28946. +     }
  28947. + #endif
  28948.   #endif
  28949.   
  28950.     /* Now turn the rtl into assembler code.  */
  28951. ***************
  28952. *** 3267,3275 ****
  28953.   
  28954.     reload_completed = 0;
  28955.   
  28956. -   /* Clear out the insn_length contents now that they are no longer valid.  */
  28957. -   init_insn_lengths ();
  28958.     /* Clear out the real_constant_chain before some of the rtx's
  28959.        it runs through become garbage.  */
  28960.   
  28961. --- 3498,3503 ----
  28962. ***************
  28963. *** 3451,3460 ****
  28964. --- 3679,3690 ----
  28965.                dbr_sched_dump = 1;
  28966.                flow_dump = 1;
  28967.                global_reg_dump = 1;
  28968. +             memory_simplify_dump = 1; /* intel2 */
  28969.                jump_opt_dump = 1;
  28970.                jump2_opt_dump = 1;
  28971.                local_reg_dump = 1;
  28972.                loop_dump = 1;
  28973. +              loop2_dump = 1; /* intel1 */
  28974.                rtl_dump = 1;
  28975.                cse_dump = 1, cse2_dump = 1;
  28976.                sched_dump = 1;
  28977. ***************
  28978. *** 3476,3481 ****
  28979. --- 3706,3716 ----
  28980.             case 'g':
  28981.               global_reg_dump = 1;
  28982.               break;
  28983. +           /* intel2 - begin */
  28984. +           case 'b':
  28985. +             memory_simplify_dump = 1;
  28986. +             break;
  28987. +           /* intel2 - end */
  28988.             case 'j':
  28989.               jump_opt_dump = 1;
  28990.               break;
  28991. ***************
  28992. *** 3488,3493 ****
  28993. --- 3723,3732 ----
  28994.             case 'L':
  28995.               loop_dump = 1;
  28996.               break;
  28997. +             /* intel1 */
  28998. +           case 'A':
  28999. +             loop2_dump = 1;
  29000. +             break;
  29001.             case 'm':
  29002.               flag_print_mem = 1;
  29003.               break;
  29004. ***************
  29005. *** 3791,3798 ****
  29006.           use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS;
  29007.   #endif          
  29008.             if (write_symbols == NO_DEBUG)
  29009. !         warning ("`-%s' not supported by this configuration of GCC",
  29010. !              str);
  29011.             else if (level == 0)
  29012.           write_symbols = NO_DEBUG;
  29013.             else
  29014. --- 4030,4036 ----
  29015.           use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS;
  29016.   #endif          
  29017.             if (write_symbols == NO_DEBUG)
  29018. !         warning ("`-%s' option not supported on this version of GCC", str);
  29019.             else if (level == 0)
  29020.           write_symbols = NO_DEBUG;
  29021.             else
  29022. ***************
  29023. *** 3827,3833 ****
  29024.       {
  29025.   #ifndef TARGET_SUPPORTS_BYTECODE
  29026.         /* Just die with a fatal error if not supported */
  29027. !       fatal ("-fbytecode not supporter for this target");
  29028.   #else
  29029.         bc_initialize ();
  29030.   #endif
  29031. --- 4065,4071 ----
  29032.       {
  29033.   #ifndef TARGET_SUPPORTS_BYTECODE
  29034.         /* Just die with a fatal error if not supported */
  29035. !       fatal ("-fbytecode not supported for this target");
  29036.   #else
  29037.         bc_initialize ();
  29038.   #endif
  29039. ***************
  29040. *** 3851,3857 ****
  29041.     if (write_symbols == DWARF_DEBUG
  29042.         && strcmp (language_string, "GNU C++") == 0)
  29043.       {
  29044. !       warning ("-g option not supported for C++ on systems using the DWARF debugging format");
  29045.         write_symbols = NO_DEBUG;
  29046.       }
  29047.   #endif /* defined(DWARF_DEBUGGING_INFO) */
  29048. --- 4089,4095 ----
  29049.     if (write_symbols == DWARF_DEBUG
  29050.         && strcmp (language_string, "GNU C++") == 0)
  29051.       {
  29052. !       warning ("-g option not supported for C++ on SVR4 systems");
  29053.         write_symbols = NO_DEBUG;
  29054.       }
  29055.   #endif /* defined(DWARF_DEBUGGING_INFO) */
  29056. ***************
  29057. *** 3893,3898 ****
  29058. --- 4131,4139 ----
  29059.   #ifdef TARGET_VERSION
  29060.         TARGET_VERSION;
  29061.   #endif
  29062. + #ifdef SUB_TARGET_VERSION
  29063. +       SUB_TARGET_VERSION;
  29064. + #endif
  29065.   #ifdef __GNUC__
  29066.   #ifndef __VERSION__
  29067.   #define __VERSION__ "[unknown]"
  29068. ***************
  29069. *** 3910,3915 ****
  29070. --- 4151,4159 ----
  29071.   #if !defined(OS2) && !defined(VMS) && !defined(_WIN32)
  29072.     if (flag_print_mem)
  29073.       {
  29074. + #ifdef __alpha
  29075. +       char *sbrk ();
  29076. + #endif
  29077.         char *lim = (char *) sbrk (0);
  29078.   
  29079.         fprintf (stderr, "Data size %d.\n",
  29080. diff -rNci gcc-2.7.2/tree.c gcc-2.7.2p/tree.c
  29081. *** gcc-2.7.2/tree.c    Mon Oct  2 01:26:56 1995
  29082. --- gcc-2.7.2p/tree.c    Thu Jun 15 12:10:23 1995
  29083. ***************
  29084. *** 2058,2070 ****
  29085.       case BIT_FIELD_REF:
  29086.         return staticp (TREE_OPERAND (arg, 0));
  29087.   
  29088. - #if 0
  29089. -        /* This case is technically correct, but results in setting
  29090. -       TREE_CONSTANT on ADDR_EXPRs that cannot be evaluated at
  29091. -       compile time.  */
  29092.       case INDIRECT_REF:
  29093.         return TREE_CONSTANT (TREE_OPERAND (arg, 0));
  29094. - #endif
  29095.   
  29096.       case ARRAY_REF:
  29097.         if (TREE_CODE (TYPE_SIZE (TREE_TYPE (arg))) == INTEGER_CST
  29098. --- 2058,2065 ----
  29099. ***************
  29100. *** 2115,2121 ****
  29101.        literal node. */
  29102.   
  29103.     if (TREE_CONSTANT (t) || (TREE_READONLY (t) && ! TREE_SIDE_EFFECTS (t))
  29104. !       || TREE_CODE (t) == SAVE_EXPR || TREE_CODE (t) == ERROR_MARK)
  29105.       return t;
  29106.   
  29107.     /* If T contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
  29108. --- 2110,2116 ----
  29109.        literal node. */
  29110.   
  29111.     if (TREE_CONSTANT (t) || (TREE_READONLY (t) && ! TREE_SIDE_EFFECTS (t))
  29112. !       || TREE_CODE (t) == SAVE_EXPR)
  29113.       return t;
  29114.   
  29115.     /* If T contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
  29116. ***************
  29117. *** 3598,3604 ****
  29118.        handled above.  If this is a language-specific tree code, we can't
  29119.        trust what might be in the operand, so say we don't know
  29120.        the situation.  */
  29121. !   if ((int) code1
  29122.         >= sizeof standard_tree_code_type / sizeof standard_tree_code_type[0])
  29123.       return -1;
  29124.   
  29125. --- 3593,3599 ----
  29126.        handled above.  If this is a language-specific tree code, we can't
  29127.        trust what might be in the operand, so say we don't know
  29128.        the situation.  */
  29129. !   if (code1
  29130.         >= sizeof standard_tree_code_type / sizeof standard_tree_code_type[0])
  29131.       return -1;
  29132.   
  29133. diff -rNci gcc-2.7.2/tree.h gcc-2.7.2p/tree.h
  29134. *** gcc-2.7.2/tree.h    Mon Sep 25 21:49:40 1995
  29135. --- gcc-2.7.2p/tree.h    Thu Jun 15 12:10:49 1995
  29136. ***************
  29137. *** 1289,1295 ****
  29138.   extern tree size_int            PROTO((unsigned HOST_WIDE_INT));
  29139.   extern tree round_up            PROTO((tree, int));
  29140.   extern tree get_pending_sizes        PROTO((void));
  29141. - extern void put_pending_sizes        PROTO((tree));
  29142.   
  29143.   /* Type for sizes of data-type.  */
  29144.   
  29145. --- 1289,1294 ----
  29146. ***************
  29147. *** 1298,1304 ****
  29148.   /* If nonzero, an upper limit on alignment of structure fields, in bits. */
  29149.   extern int maximum_field_alignment;
  29150.   
  29151. ! /* If non-zero, the alignment of a bitstring or (power-)set value, in bits. */
  29152.   extern int set_alignment;
  29153.   
  29154.   /* Concatenate two lists (chains of TREE_LIST nodes) X and Y
  29155. --- 1297,1303 ----
  29156.   /* If nonzero, an upper limit on alignment of structure fields, in bits. */
  29157.   extern int maximum_field_alignment;
  29158.   
  29159. ! /* If non-zero, the alignment of a bitsting or (power-)set value, in bits. */
  29160.   extern int set_alignment;
  29161.   
  29162.   /* Concatenate two lists (chains of TREE_LIST nodes) X and Y
  29163. diff -rNci gcc-2.7.2/unroll.c gcc-2.7.2p/unroll.c
  29164. *** gcc-2.7.2/unroll.c    Sat Aug 19 21:33:26 1995
  29165. --- gcc-2.7.2p/unroll.c    Tue Jan 23 09:25:32 1996
  29166. ***************
  29167. *** 156,161 ****
  29168. --- 156,164 ----
  29169.   #include <stdio.h>
  29170.   #include "loop.h"
  29171.   
  29172. + /* intel1 */
  29173. + extern FILE *loop_dump_stream;
  29174.   /* This controls which loops are unrolled, and by how much we unroll
  29175.      them.  */
  29176.   
  29177. ***************
  29178. *** 853,871 ****
  29179.         for (i = 0; i < unroll_number; i++)
  29180.           labels[i] = gen_label_rtx ();
  29181.   
  29182. -       /* Check for the case where the initial value is greater than or equal
  29183. -          to the final value.  In that case, we want to execute exactly
  29184. -          one loop iteration.  The code below will fail for this case.  */
  29185. -       emit_cmp_insn (initial_value, final_value, neg_inc ? LE : GE,
  29186. -              NULL_RTX, mode, 0, 0);
  29187. -       if (neg_inc)
  29188. -         emit_jump_insn (gen_ble (labels[1]));
  29189. -       else
  29190. -         emit_jump_insn (gen_bge (labels[1]));
  29191. -       JUMP_LABEL (get_last_insn ()) = labels[1];
  29192. -       LABEL_NUSES (labels[1])++;
  29193.         /* Assuming the unroll_number is 4, and the increment is 2, then
  29194.            for a negative increment:    for a positive increment:
  29195.            diff = 0,1   precond 0    diff = 0,7   precond 0
  29196. --- 856,861 ----
  29197. ***************
  29198. *** 882,909 ****
  29199.         for (i = 0; i < unroll_number - 1; i++)
  29200.           {
  29201.             int cmp_const;
  29202. -           enum rtx_code cmp_code;
  29203.   
  29204.             /* For negative increments, must invert the constant compared
  29205.            against, except when comparing against zero.  */
  29206.             if (i == 0)
  29207. !         {
  29208. !           cmp_const = 0;
  29209. !           cmp_code = EQ;
  29210. !         }
  29211.             else if (neg_inc)
  29212. !         {
  29213. !           cmp_const = unroll_number - i;
  29214. !           cmp_code = GE;
  29215. !         }
  29216.             else
  29217. !         {
  29218. !           cmp_const = i;
  29219. !           cmp_code = LE;
  29220. !         }
  29221.   
  29222.             emit_cmp_insn (diff, GEN_INT (abs_inc * cmp_const),
  29223. !                  cmp_code, NULL_RTX, mode, 0, 0);
  29224.   
  29225.             if (i == 0)
  29226.           emit_jump_insn (gen_beq (labels[i]));
  29227. --- 872,889 ----
  29228.         for (i = 0; i < unroll_number - 1; i++)
  29229.           {
  29230.             int cmp_const;
  29231.   
  29232.             /* For negative increments, must invert the constant compared
  29233.            against, except when comparing against zero.  */
  29234.             if (i == 0)
  29235. !         cmp_const = 0;
  29236.             else if (neg_inc)
  29237. !         cmp_const = unroll_number - i;
  29238.             else
  29239. !         cmp_const = i;
  29240.   
  29241.             emit_cmp_insn (diff, GEN_INT (abs_inc * cmp_const),
  29242. !                  EQ, NULL_RTX, mode, 0, 0);
  29243.   
  29244.             if (i == 0)
  29245.           emit_jump_insn (gen_beq (labels[i]));
  29246. ***************
  29247. *** 927,946 ****
  29248.         if (abs_inc != 1)
  29249.           {
  29250.             int cmp_const;
  29251. -           enum rtx_code cmp_code;
  29252.   
  29253.             if (neg_inc)
  29254. !         {
  29255. !           cmp_const = abs_inc - 1;
  29256. !           cmp_code = LE;
  29257. !         }
  29258.             else
  29259. !         {
  29260. !           cmp_const = abs_inc * (unroll_number - 1) + 1;
  29261. !           cmp_code = GE;
  29262. !         }
  29263.   
  29264. !           emit_cmp_insn (diff, GEN_INT (cmp_const), cmp_code, NULL_RTX,
  29265.                    mode, 0, 0);
  29266.   
  29267.             if (neg_inc)
  29268. --- 907,919 ----
  29269.         if (abs_inc != 1)
  29270.           {
  29271.             int cmp_const;
  29272.   
  29273.             if (neg_inc)
  29274. !         cmp_const = abs_inc - 1;
  29275.             else
  29276. !         cmp_const = abs_inc * (unroll_number - 1) + 1;
  29277.   
  29278. !           emit_cmp_insn (diff, GEN_INT (cmp_const), EQ, NULL_RTX,
  29279.                    mode, 0, 0);
  29280.   
  29281.             if (neg_inc)
  29282. ***************
  29283. *** 1412,1424 ****
  29284.        one of the LO_SUM rtx.  */
  29285.         if (GET_CODE (increment) == LO_SUM)
  29286.       increment = XEXP (increment, 1);
  29287. !       else if (GET_CODE (increment) == IOR
  29288. !            || GET_CODE (increment) == ASHIFT)
  29289.       {
  29290. !       /* The rs6000 port loads some constants with IOR.
  29291. !          The alpha port loads some constants with ASHIFT.  */
  29292.         rtx second_part = XEXP (increment, 1);
  29293. -       enum rtx_code code = GET_CODE (increment);
  29294.   
  29295.         src_insn = PREV_INSN (src_insn);
  29296.         increment = SET_SRC (PATTERN (src_insn));
  29297. --- 1385,1394 ----
  29298.        one of the LO_SUM rtx.  */
  29299.         if (GET_CODE (increment) == LO_SUM)
  29300.       increment = XEXP (increment, 1);
  29301. !       else if (GET_CODE (increment) == IOR)
  29302.       {
  29303. !       /* The rs6000 port loads some constants with IOR.  */
  29304.         rtx second_part = XEXP (increment, 1);
  29305.   
  29306.         src_insn = PREV_INSN (src_insn);
  29307.         increment = SET_SRC (PATTERN (src_insn));
  29308. ***************
  29309. *** 1429,1438 ****
  29310.             || GET_CODE (increment) != CONST_INT)
  29311.           abort ();
  29312.   
  29313. !       if (code == IOR)
  29314. !         increment = GEN_INT (INTVAL (increment) | INTVAL (second_part));
  29315. !       else
  29316. !         increment = GEN_INT (INTVAL (increment) << INTVAL (second_part));
  29317.       }
  29318.   
  29319.         if (GET_CODE (increment) != CONST_INT)
  29320. --- 1399,1405 ----
  29321.             || GET_CODE (increment) != CONST_INT)
  29322.           abort ();
  29323.   
  29324. !       increment = GEN_INT (INTVAL (increment) | INTVAL (second_part));
  29325.       }
  29326.   
  29327.         if (GET_CODE (increment) != CONST_INT)
  29328. ***************
  29329. *** 1770,1775 ****
  29330. --- 1737,1778 ----
  29331.         else
  29332.           {
  29333.             pattern = copy_rtx_and_substitute (pattern, map);
  29334. + /* intel1 since a DEST_ADDR giv may be only a part of an address
  29335. +    then just substituting reg+const for reg may result in an
  29336. +    invalid insn - we check for that and try to make it good */
  29337. + #if REDUCE_INDEX || SAVE_ON_REGS
  29338. +               if(GET_CODE(PATTERN(insn))==SET)
  29339. +             {
  29340. +               int dummy;
  29341. +               rtx try_to_make_good(); /* see loop.c */
  29342. +               if(recog(pattern,insn,&dummy)==-1)
  29343. +                 {
  29344. +                   try_to_make_good(SET_SRC(pattern));
  29345. +                   try_to_make_good(SET_DEST(pattern));
  29346. +                     if(recog(pattern,insn,&dummy)==-1)
  29347. +                     {
  29348. +                       fprintf(stderr,"bad pattern in insn not better:\n");
  29349. +                       debug_rtx(insn);
  29350. +                       abort();
  29351. +                     }
  29352. +                 }
  29353. +             }
  29354. + #endif
  29355. +           /* intel1 Don't want to be reusing STACK_MODE registers
  29356. +              since that inhibits scheduling opportunities */
  29357. + #ifdef STACK_REGS
  29358. + #ifdef IS_STACK_MODE
  29359. + #ifdef ONLY_STACK_REG_REORDER
  29360. +             if (GET_CODE (pattern) == SET && GET_CODE (SET_DEST (pattern)) == REG
  29361. +                 && IS_STACK_MODE (GET_MODE (SET_DEST (pattern))))
  29362. +               {
  29363. +             tem = gen_reg_rtx (GET_MODE (SET_DEST (pattern)));
  29364. +             map->reg_map[REGNO (SET_DEST (PATTERN (insn)))] = tem;
  29365. +             SET_DEST (pattern) = tem;
  29366. +               }
  29367. + #endif
  29368. + #endif
  29369. + #endif
  29370.             copy = emit_insn (pattern);
  29371.           }
  29372.         REG_NOTES (copy) = initial_reg_note_copy (REG_NOTES (insn), map);
  29373. ***************
  29374. *** 2393,2405 ****
  29375.        it is unsafe to split the biv since it may not have the proper
  29376.        value on loop exit.  */
  29377.   
  29378. !       /* loop_number_exit_count is non-zero if the loop has an exit other than
  29379.        a fall through at the end.  */
  29380.   
  29381.         biv_splittable = 1;
  29382.         biv_final_value = 0;
  29383.         if (unroll_type != UNROLL_COMPLETELY
  29384. !       && (loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]]
  29385.             || unroll_type == UNROLL_NAIVE)
  29386.         && (uid_luid[regno_last_uid[bl->regno]] >= INSN_LUID (loop_end)
  29387.             || ! bl->init_insn
  29388. --- 2396,2408 ----
  29389.        it is unsafe to split the biv since it may not have the proper
  29390.        value on loop exit.  */
  29391.   
  29392. !       /* loop_number_exit_labels is non-zero if the loop has an exit other than
  29393.        a fall through at the end.  */
  29394.   
  29395.         biv_splittable = 1;
  29396.         biv_final_value = 0;
  29397.         if (unroll_type != UNROLL_COMPLETELY
  29398. !       && (loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]]
  29399.             || unroll_type == UNROLL_NAIVE)
  29400.         && (uid_luid[regno_last_uid[bl->regno]] >= INSN_LUID (loop_end)
  29401.             || ! bl->init_insn
  29402. ***************
  29403. *** 2433,2445 ****
  29404.           {
  29405.             /* If the initial value of the biv is itself (i.e. it is too
  29406.            complicated for strength_reduce to compute), or is a hard
  29407. !          register, or it isn't invariant, then we must create a new
  29408. !          pseudo reg to hold the initial value of the biv.  */
  29409.   
  29410.             if (GET_CODE (bl->initial_value) == REG
  29411.             && (REGNO (bl->initial_value) == bl->regno
  29412. !               || REGNO (bl->initial_value) < FIRST_PSEUDO_REGISTER
  29413. !               || ! invariant_p (bl->initial_value)))
  29414.           {
  29415.             rtx tem = gen_reg_rtx (bl->biv->mode);
  29416.             
  29417. --- 2436,2447 ----
  29418.           {
  29419.             /* If the initial value of the biv is itself (i.e. it is too
  29420.            complicated for strength_reduce to compute), or is a hard
  29421. !          register, then we must create a new pseudo reg to hold the
  29422. !          initial value of the biv.  */
  29423.   
  29424.             if (GET_CODE (bl->initial_value) == REG
  29425.             && (REGNO (bl->initial_value) == bl->regno
  29426. !               || REGNO (bl->initial_value) < FIRST_PSEUDO_REGISTER))
  29427.           {
  29428.             rtx tem = gen_reg_rtx (bl->biv->mode);
  29429.             
  29430. ***************
  29431. *** 2487,2493 ****
  29432.            loop to ensure that it will always be executed no matter
  29433.            how the loop exits.  Otherwise emit the insn after the loop,
  29434.            since this is slightly more efficient.  */
  29435. !       if (! loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]])
  29436.           emit_insn_before (gen_move_insn (bl->biv->src_reg,
  29437.                            biv_final_value),
  29438.                     end_insert_before);
  29439. --- 2489,2495 ----
  29440.            loop to ensure that it will always be executed no matter
  29441.            how the loop exits.  Otherwise emit the insn after the loop,
  29442.            since this is slightly more efficient.  */
  29443. !       if (! loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]])
  29444.           emit_insn_before (gen_move_insn (bl->biv->src_reg,
  29445.                            biv_final_value),
  29446.                     end_insert_before);
  29447. ***************
  29448. *** 2610,2616 ****
  29449.   
  29450.         final_value = 0;
  29451.         if (unroll_type != UNROLL_COMPLETELY
  29452. !       && (loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]]
  29453.             || unroll_type == UNROLL_NAIVE)
  29454.         && v->giv_type != DEST_ADDR
  29455.         && ((regno_first_uid[REGNO (v->dest_reg)] != INSN_UID (v->insn)
  29456. --- 2612,2618 ----
  29457.   
  29458.         final_value = 0;
  29459.         if (unroll_type != UNROLL_COMPLETELY
  29460. !       && (loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]]
  29461.             || unroll_type == UNROLL_NAIVE)
  29462.         && v->giv_type != DEST_ADDR
  29463.         && ((regno_first_uid[REGNO (v->dest_reg)] != INSN_UID (v->insn)
  29464. ***************
  29465. *** 2950,2975 ****
  29466.     rtx insn, label;
  29467.     enum rtx_code code;
  29468.     int jump_count = 0;
  29469. -   int label_count = 0;
  29470. -   int this_loop_num = uid_loop_num[INSN_UID (loop_start)];
  29471. -   /* In addition to checking all exits of this loop, we must also check
  29472. -      all exits of inner nested loops that would exit this loop.  We don't
  29473. -      have any way to identify those, so we just give up if there are any
  29474. -      such inner loop exits.  */
  29475. -      
  29476. -   for (label = loop_number_exit_labels[this_loop_num]; label;
  29477. -        label = LABEL_NEXTREF (label))
  29478. -     label_count++;
  29479. -   if (label_count != loop_number_exit_count[this_loop_num])
  29480. -     return 0;
  29481.   
  29482.     /* HACK: Must also search the loop fall through exit, create a label_ref
  29483.        here which points to the loop_end, and append the loop_number_exit_labels
  29484.        list to it.  */
  29485.     label = gen_rtx (LABEL_REF, VOIDmode, loop_end);
  29486. !   LABEL_NEXTREF (label) = loop_number_exit_labels[this_loop_num];
  29487.   
  29488.     for ( ; label; label = LABEL_NEXTREF (label))
  29489.       {
  29490. --- 2952,2964 ----
  29491.     rtx insn, label;
  29492.     enum rtx_code code;
  29493.     int jump_count = 0;
  29494.   
  29495.     /* HACK: Must also search the loop fall through exit, create a label_ref
  29496.        here which points to the loop_end, and append the loop_number_exit_labels
  29497.        list to it.  */
  29498.     label = gen_rtx (LABEL_REF, VOIDmode, loop_end);
  29499. !   LABEL_NEXTREF (label)
  29500. !     = loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]];
  29501.   
  29502.     for ( ; label; label = LABEL_NEXTREF (label))
  29503.       {
  29504. ***************
  29505. *** 3048,3054 ****
  29506.        value of the biv must be invariant.  */
  29507.   
  29508.     if (loop_n_iterations != 0
  29509. !       && ! loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]]
  29510.         && invariant_p (bl->initial_value))
  29511.       {
  29512.         increment = biv_total_increment (bl, loop_start, loop_end);
  29513. --- 3037,3043 ----
  29514.        value of the biv must be invariant.  */
  29515.   
  29516.     if (loop_n_iterations != 0
  29517. !       && ! loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]]
  29518.         && invariant_p (bl->initial_value))
  29519.       {
  29520.         increment = biv_total_increment (bl, loop_start, loop_end);
  29521. ***************
  29522. *** 3126,3132 ****
  29523.        to be known.  */
  29524.   
  29525.     if (loop_n_iterations != 0
  29526. !       && ! loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]])
  29527.       {
  29528.         /* ?? It is tempting to use the biv's value here since these insns will
  29529.        be put after the loop, and hence the biv will have its final value
  29530. --- 3115,3121 ----
  29531.        to be known.  */
  29532.   
  29533.     if (loop_n_iterations != 0
  29534. !       && ! loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]])
  29535.       {
  29536.         /* ?? It is tempting to use the biv's value here since these insns will
  29537.        be put after the loop, and hence the biv will have its final value
  29538. diff -rNci gcc-2.7.2/varasm.c gcc-2.7.2p/varasm.c
  29539. *** gcc-2.7.2/varasm.c    Thu Aug 31 23:02:53 1995
  29540. --- gcc-2.7.2p/varasm.c    Tue Jan 23 09:25:32 1996
  29541. ***************
  29542. *** 78,90 ****
  29543.   
  29544.   /* Number for making the label on the next
  29545.      constant that is stored in memory.  */
  29546. ! int const_labelno;
  29547.   
  29548.   /* Number for making the label on the next
  29549.      static variable internal to a function.  */
  29550. ! int var_labelno;
  29551.   
  29552.   /* Carry information from ASM_DECLARE_OBJECT_NAME
  29553.      to ASM_FINISH_DECLARE_OBJECT.  */
  29554. --- 78,90 ----
  29555.   
  29556.   /* Number for making the label on the next
  29557.      constant that is stored in memory.  */
  29558. ! /* intel1 */
  29559. ! static int const_labelno = 0;
  29560.   
  29561.   /* Number for making the label on the next
  29562.      static variable internal to a function.  */
  29563. ! /* intel1 */
  29564. ! int var_labelno = 0;
  29565.   
  29566.   /* Carry information from ASM_DECLARE_OBJECT_NAME
  29567.      to ASM_FINISH_DECLARE_OBJECT.  */
  29568. ***************
  29569. *** 1147,1158 ****
  29570.           else
  29571.             {
  29572.   #ifdef ASM_OUTPUT_ALIGNED_COMMON
  29573. !         ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size,
  29574. !                        DECL_ALIGN (decl));
  29575.   #else
  29576. !         ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
  29577.   #endif
  29578. !           }
  29579.       }
  29580.         else
  29581.       {
  29582. --- 1147,1169 ----
  29583.           else
  29584.             {
  29585.   #ifdef ASM_OUTPUT_ALIGNED_COMMON
  29586. ! /* intel1 */
  29587. ! #ifdef ALIGN_DFmode
  29588. !               if (DECL_MODE (decl) == DFmode
  29589. !                   && DECL_ALIGN (decl) 
  29590. !                     == (GET_MODE_SIZE (SFmode) * BITS_PER_UNIT))
  29591. !                 {
  29592. !           ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size, 
  29593. !           GET_MODE_SIZE (DFmode) * BITS_PER_UNIT);
  29594. !                 }
  29595. !               else
  29596. ! #endif
  29597. !           ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size,
  29598. !                            DECL_ALIGN (decl));
  29599.   #else
  29600. !           ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
  29601.   #endif
  29602. !         }
  29603.       }
  29604.         else
  29605.       {
  29606. ***************
  29607. *** 1168,1179 ****
  29608.           else
  29609.             {
  29610.   #ifdef ASM_OUTPUT_ALIGNED_LOCAL
  29611. !         ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size,
  29612. !                       DECL_ALIGN (decl));
  29613.   #else
  29614. !         ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
  29615.   #endif
  29616. !           }
  29617.       }
  29618.         goto finish;
  29619.       }
  29620. --- 1179,1201 ----
  29621.           else
  29622.             {
  29623.   #ifdef ASM_OUTPUT_ALIGNED_LOCAL
  29624. ! /* intel1 */
  29625. ! #ifdef ALIGN_DFmode
  29626. !             if (DECL_MODE (decl) == DFmode
  29627. !                 && DECL_ALIGN (decl) 
  29628. !                   == (GET_MODE_SIZE (SFmode) * BITS_PER_UNIT))
  29629. !               {
  29630. !         ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size, 
  29631. !         GET_MODE_SIZE (DFmode) * BITS_PER_UNIT);
  29632. !               }
  29633. !             else
  29634. ! #endif
  29635. !         ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size,
  29636. !                       DECL_ALIGN (decl));
  29637.   #else
  29638. !         ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
  29639.   #endif
  29640. !         }
  29641.       }
  29642.         goto finish;
  29643.       }
  29644. ***************
  29645. *** 1327,1332 ****
  29646. --- 1349,1362 ----
  29647.        from it in get_pointer_alignment.  */
  29648.     DECL_ALIGN (decl) = align;
  29649.   
  29650. + /* intel1 */
  29651. + #ifdef ALIGN_DFmode
  29652. +     if (DECL_MODE (decl) == DFmode
  29653. +         && DECL_ALIGN (decl) == (GET_MODE_SIZE (SFmode) * BITS_PER_UNIT))
  29654. +       {
  29655. +         align = GET_MODE_SIZE (DFmode) * BITS_PER_UNIT;
  29656. +       }
  29657. + #endif
  29658.     if (align > BITS_PER_UNIT)
  29659.       {
  29660.         if (output_bytecode)
  29661. ***************
  29662. *** 1575,1581 ****
  29663.     if (name[0] == '*')
  29664.       {
  29665.         if (output_bytecode)
  29666. !     bc_emit_labelref (name, 0);
  29667.         else
  29668.       fputs (&name[1], file);
  29669.       }
  29670. --- 1605,1611 ----
  29671.     if (name[0] == '*')
  29672.       {
  29673.         if (output_bytecode)
  29674. !     bc_emit_labelref (name);
  29675.         else
  29676.       fputs (&name[1], file);
  29677.       }
  29678. ***************
  29679. *** 2954,2960 ****
  29680.     union {
  29681.       union real_extract du;
  29682.       struct addr_const addr;
  29683. -     struct {HOST_WIDE_INT high, low;} di;
  29684.     } un;
  29685.   };
  29686.   
  29687. --- 2984,2989 ----
  29688. ***************
  29689. *** 2985,3000 ****
  29690.       case CONST_DOUBLE:
  29691.         value->kind = RTX_DOUBLE;
  29692.         if (GET_MODE (x) != VOIDmode)
  29693. !     {
  29694. !       value->mode = GET_MODE (x);
  29695. !       bcopy ((char *) &CONST_DOUBLE_LOW (x),
  29696. !          (char *) &value->un.du, sizeof value->un.du);
  29697. !     }
  29698. !       else
  29699. !     {
  29700. !       value->un.di.low = CONST_DOUBLE_LOW (x);
  29701. !       value->un.di.high = CONST_DOUBLE_HIGH (x);
  29702. !     }
  29703.         break;
  29704.   
  29705.       case CONST_INT:
  29706. --- 3014,3022 ----
  29707.       case CONST_DOUBLE:
  29708.         value->kind = RTX_DOUBLE;
  29709.         if (GET_MODE (x) != VOIDmode)
  29710. !     value->mode = GET_MODE (x);
  29711. !       bcopy ((char *) &CONST_DOUBLE_LOW (x),
  29712. !          (char *) &value->un.du, sizeof value->un.du);
  29713.         break;
  29714.   
  29715.       case CONST_INT:
  29716. ***************
  29717. *** 3198,3203 ****
  29718. --- 3220,3229 ----
  29719.         align = (mode == VOIDmode) ? UNITS_PER_WORD : GET_MODE_SIZE (mode);
  29720.         if (align > BIGGEST_ALIGNMENT / BITS_PER_UNIT)
  29721.       align = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
  29722. +       /* intel1 */
  29723. + #ifdef ALIGN_DFmode
  29724. +       align = (mode == DFmode) ? GET_MODE_SIZE (mode) : align;
  29725. + #endif
  29726.   
  29727.         pool_offset += align - 1;
  29728.         pool_offset &= ~ (align - 1);
  29729. ***************
  29730. *** 3693,3700 ****
  29731.     else
  29732.       if (size == 4
  29733.       && TREE_CODE (TREE_OPERAND (addr_part, 0)) == VAR_DECL)
  29734. !       bc_emit_labelref (IDENTIFIER_POINTER
  29735. !             (DECL_ASSEMBLER_NAME (TREE_OPERAND (addr_part, 0))),
  29736.               TREE_INT_CST_LOW (const_part));
  29737.       else
  29738.         abort ();        /* FIXME: there may be more cases.  */
  29739. --- 3719,3725 ----
  29740.     else
  29741.       if (size == 4
  29742.       && TREE_CODE (TREE_OPERAND (addr_part, 0)) == VAR_DECL)
  29743. !       bc_emit_labelref (DECL_ASSEMBLER_NAME (TREE_OPERAND (addr_part, 0)),
  29744.               TREE_INT_CST_LOW (const_part));
  29745.       else
  29746.         abort ();        /* FIXME: there may be more cases.  */
  29747. diff -rNci gcc-2.7.2/version.c gcc-2.7.2p/version.c
  29748. *** gcc-2.7.2/version.c    Sun Nov 26 16:20:43 1995
  29749. --- gcc-2.7.2p/version.c    Tue Jan 23 09:54:59 1996
  29750. ***************
  29751. *** 1 ****
  29752. ! char *version_string = "2.7.2";
  29753. --- 1 ----
  29754. ! char *version_string = "2.7.2p";
  29755.